Compare commits

...

12 Commits

13 changed files with 683 additions and 316 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
**/node_modules/** **/node_modules/**
dist/** dist/**
desktop.ini desktop.ini
.continue/**

453
package-lock.json generated
View File

@ -28,18 +28,14 @@
} }
}, },
"node_modules/@jridgewell/gen-mapping": { "node_modules/@jridgewell/gen-mapping": {
"version": "0.3.5", "version": "0.3.12",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24" "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
} }
}, },
"node_modules/@jridgewell/resolve-uri": { "node_modules/@jridgewell/resolve-uri": {
@ -52,20 +48,10 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": { "node_modules/@jridgewell/source-map": {
"version": "0.3.6", "version": "0.3.10",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -74,16 +60,16 @@
} }
}, },
"node_modules/@jridgewell/sourcemap-codec": { "node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0", "version": "1.5.4",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@jridgewell/trace-mapping": { "node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25", "version": "0.3.29",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -114,16 +100,16 @@
} }
}, },
"node_modules/@types/estree": { "node_modules/@types/estree": {
"version": "1.0.6", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/google-apps-script": { "node_modules/@types/google-apps-script": {
"version": "1.0.85", "version": "1.0.99",
"resolved": "https://registry.npmjs.org/@types/google-apps-script/-/google-apps-script-1.0.85.tgz", "resolved": "https://registry.npmjs.org/@types/google-apps-script/-/google-apps-script-1.0.99.tgz",
"integrity": "sha512-O5w3PxI75uqU4d7t24ukQtU87OZ2j0vQp3VWmx9sJ6PTwBRvGhMA+qWShKNetofI8TYaVd8tFzBQXgv3e7ycCQ==", "integrity": "sha512-JrOXCWxYmY1ePWZXQxegrVMdXS0vuN69AMUfDIvfz5aLZ+El5JcYllwzeXeFC1YoM3lMWtPNGjgeTxlz8jih6w==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -135,13 +121,13 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.9.0", "version": "24.1.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
"integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.8" "undici-types": "~7.8.0"
} }
}, },
"node_modules/@webassemblyjs/ast": { "node_modules/@webassemblyjs/ast": {
@ -367,9 +353,9 @@
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.14.0", "version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -379,31 +365,65 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/acorn-import-phases": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
"integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10.13.0"
},
"peerDependencies": {
"acorn": "^8.14.0"
}
},
"node_modules/ajv": { "node_modules/ajv": {
"version": "6.12.6", "version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"fast-deep-equal": "^3.1.1", "fast-deep-equal": "^3.1.3",
"fast-json-stable-stringify": "^2.0.0", "fast-uri": "^3.0.1",
"json-schema-traverse": "^0.4.1", "json-schema-traverse": "^1.0.0",
"uri-js": "^4.2.2" "require-from-string": "^2.0.2"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
"url": "https://github.com/sponsors/epoberezkin" "url": "https://github.com/sponsors/epoberezkin"
} }
}, },
"node_modules/ajv-keywords": { "node_modules/ajv-formats": {
"version": "3.5.2", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
},
"peerDependencies": { "peerDependencies": {
"ajv": "^6.9.1" "ajv": "^8.0.0"
},
"peerDependenciesMeta": {
"ajv": {
"optional": true
}
}
},
"node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
"peerDependencies": {
"ajv": "^8.8.2"
} }
}, },
"node_modules/ansi-styles": { "node_modules/ansi-styles": {
@ -430,9 +450,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "2.0.1", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -453,9 +473,9 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.24.2", "version": "4.25.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
"integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -473,10 +493,10 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001669", "caniuse-lite": "^1.0.30001726",
"electron-to-chromium": "^1.5.41", "electron-to-chromium": "^1.5.173",
"node-releases": "^2.0.18", "node-releases": "^2.0.19",
"update-browserslist-db": "^1.1.1" "update-browserslist-db": "^1.1.3"
}, },
"bin": { "bin": {
"browserslist": "cli.js" "browserslist": "cli.js"
@ -493,9 +513,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001680", "version": "1.0.30001731",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz",
"integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -590,9 +610,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.5", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -605,16 +625,16 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.57", "version": "1.5.194",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.57.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.194.tgz",
"integrity": "sha512-xS65H/tqgOwUBa5UmOuNSLuslDo7zho0y/lgQw35pnrqiZh7UOWHCeL/Bt6noJATbA6tpQJGCifsFsIRZj1Fqg==", "integrity": "sha512-SdnWJwSUot04UR51I2oPD8kuP2VI37/CADR1OHsFOUzZIvfWJBO6q11k5P/uKNyTT3cdOsnyjkrZ+DDShqYqJA==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/enhanced-resolve": { "node_modules/enhanced-resolve": {
"version": "5.17.1", "version": "5.18.2",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -639,9 +659,9 @@
} }
}, },
"node_modules/es-module-lexer": { "node_modules/es-module-lexer": {
"version": "1.5.4", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
"integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -677,27 +697,6 @@
"source-map": "~0.6.1" "source-map": "~0.6.1"
} }
}, },
"node_modules/escodegen/node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
},
"node_modules/escodegen/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/eslint-scope": { "node_modules/eslint-scope": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@ -712,6 +711,16 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/eslint-scope/node_modules/estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
},
"node_modules/esprima": { "node_modules/esprima": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@ -753,7 +762,7 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/esrecurse/node_modules/estraverse": { "node_modules/estraverse": {
"version": "5.3.0", "version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
@ -763,16 +772,6 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
},
"node_modules/esutils": { "node_modules/esutils": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@ -800,12 +799,22 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/fast-json-stable-stringify": { "node_modules/fast-uri": {
"version": "2.1.0", "version": "3.0.6",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
"dev": true, "dev": true,
"license": "MIT" "funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
}, },
"node_modules/fastest-levenshtein": { "node_modules/fastest-levenshtein": {
"version": "1.0.16", "version": "1.0.16",
@ -876,16 +885,6 @@
"estraverse": "5.3.0" "estraverse": "5.3.0"
} }
}, },
"node_modules/gas-entry-generator/node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
},
"node_modules/gas-webpack-plugin": { "node_modules/gas-webpack-plugin": {
"version": "2.6.0", "version": "2.6.0",
"resolved": "https://registry.npmjs.org/gas-webpack-plugin/-/gas-webpack-plugin-2.6.0.tgz", "resolved": "https://registry.npmjs.org/gas-webpack-plugin/-/gas-webpack-plugin-2.6.0.tgz",
@ -914,9 +913,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/graphql": { "node_modules/graphql": {
"version": "16.9.0", "version": "16.11.0",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz",
"integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
@ -994,9 +993,9 @@
} }
}, },
"node_modules/is-core-module": { "node_modules/is-core-module": {
"version": "2.15.1", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1088,9 +1087,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/json-schema-traverse": { "node_modules/json-schema-traverse": {
"version": "0.4.1", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -1195,9 +1194,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.18", "version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -1300,16 +1299,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/randombytes": { "node_modules/randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -1333,20 +1322,33 @@
"node": ">= 10.13.0" "node": ">= 10.13.0"
} }
}, },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.8", "version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"is-core-module": "^2.13.0", "is-core-module": "^2.16.0",
"path-parse": "^1.0.7", "path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0" "supports-preserve-symlinks-flag": "^1.0.0"
}, },
"bin": { "bin": {
"resolve": "bin/resolve" "resolve": "bin/resolve"
}, },
"engines": {
"node": ">= 0.4"
},
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
@ -1396,15 +1398,16 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/schema-utils": { "node_modules/schema-utils": {
"version": "3.3.0", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.8", "@types/json-schema": "^7.0.9",
"ajv": "^6.12.5", "ajv": "^8.9.0",
"ajv-keywords": "^3.5.2" "ajv-formats": "^2.1.1",
"ajv-keywords": "^5.1.0"
}, },
"engines": { "engines": {
"node": ">= 10.13.0" "node": ">= 10.13.0"
@ -1415,9 +1418,9 @@
} }
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "7.6.3", "version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"bin": { "bin": {
@ -1475,7 +1478,7 @@
}, },
"node_modules/shopify-admin-api-typings": { "node_modules/shopify-admin-api-typings": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "git+ssh://git@github.com/beepmill/shopify-admin-api-typings.git#e8ba51acff0a4e66c31ee61d62f5244ad4f4233a", "resolved": "git+ssh://git@github.com/beepmill/shopify-admin-api-typings.git#1641fa805ac6d185abfa33515f7ed265837743df",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
@ -1493,13 +1496,13 @@
} }
}, },
"node_modules/source-map": { "node_modules/source-map": {
"version": "0.7.4", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true, "dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"engines": { "engines": {
"node": ">= 8" "node": ">=0.10.0"
} }
}, },
"node_modules/source-map-support": { "node_modules/source-map-support": {
@ -1513,16 +1516,6 @@
"source-map": "^0.6.0" "source-map": "^0.6.0"
} }
}, },
"node_modules/source-map-support/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -1550,9 +1543,9 @@
} }
}, },
"node_modules/tapable": { "node_modules/tapable": {
"version": "2.2.1", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -1560,14 +1553,14 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.36.0", "version": "5.43.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
"integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2", "acorn": "^8.14.0",
"commander": "^2.20.0", "commander": "^2.20.0",
"source-map-support": "~0.5.20" "source-map-support": "~0.5.20"
}, },
@ -1579,17 +1572,17 @@
} }
}, },
"node_modules/terser-webpack-plugin": { "node_modules/terser-webpack-plugin": {
"version": "5.3.10", "version": "5.3.14",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
"integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/trace-mapping": "^0.3.20", "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5", "jest-worker": "^27.4.5",
"schema-utils": "^3.1.1", "schema-utils": "^4.3.0",
"serialize-javascript": "^6.0.1", "serialize-javascript": "^6.0.2",
"terser": "^5.26.0" "terser": "^5.31.1"
}, },
"engines": { "engines": {
"node": ">= 10.13.0" "node": ">= 10.13.0"
@ -1627,9 +1620,9 @@
} }
}, },
"node_modules/ts-loader": { "node_modules/ts-loader": {
"version": "9.5.1", "version": "9.5.2",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz",
"integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1647,6 +1640,16 @@
"webpack": "^5.0.0" "webpack": "^5.0.0"
} }
}, },
"node_modules/ts-loader/node_modules/source-map": {
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
"integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">= 12"
}
},
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.8.1", "version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@ -1655,9 +1658,9 @@
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.6.3", "version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true, "peer": true,
@ -1670,16 +1673,16 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "6.19.8", "version": "7.8.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.1.1", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
"integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -1698,7 +1701,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"escalade": "^3.2.0", "escalade": "^3.2.0",
"picocolors": "^1.1.0" "picocolors": "^1.1.1"
}, },
"bin": { "bin": {
"update-browserslist-db": "cli.js" "update-browserslist-db": "cli.js"
@ -1707,20 +1710,10 @@
"browserslist": ">= 4.21.0" "browserslist": ">= 4.21.0"
} }
}, },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
},
"node_modules/watchpack": { "node_modules/watchpack": {
"version": "2.4.2", "version": "2.4.4",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
"integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1732,21 +1725,23 @@
} }
}, },
"node_modules/webpack": { "node_modules/webpack": {
"version": "5.96.1", "version": "5.101.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.0.tgz",
"integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", "integrity": "sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/eslint-scope": "^3.7.7", "@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.6", "@types/estree": "^1.0.8",
"@webassemblyjs/ast": "^1.12.1", "@types/json-schema": "^7.0.15",
"@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/ast": "^1.14.1",
"@webassemblyjs/wasm-parser": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.14.1",
"acorn": "^8.14.0", "@webassemblyjs/wasm-parser": "^1.14.1",
"acorn": "^8.15.0",
"acorn-import-phases": "^1.0.3",
"browserslist": "^4.24.0", "browserslist": "^4.24.0",
"chrome-trace-event": "^1.0.2", "chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.17.1", "enhanced-resolve": "^5.17.2",
"es-module-lexer": "^1.2.1", "es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1", "eslint-scope": "5.1.1",
"events": "^3.2.0", "events": "^3.2.0",
@ -1756,11 +1751,11 @@
"loader-runner": "^4.2.0", "loader-runner": "^4.2.0",
"mime-types": "^2.1.27", "mime-types": "^2.1.27",
"neo-async": "^2.6.2", "neo-async": "^2.6.2",
"schema-utils": "^3.2.0", "schema-utils": "^4.3.2",
"tapable": "^2.1.1", "tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.10", "terser-webpack-plugin": "^5.3.11",
"watchpack": "^2.4.1", "watchpack": "^2.4.1",
"webpack-sources": "^3.2.3" "webpack-sources": "^3.3.3"
}, },
"bin": { "bin": {
"webpack": "bin/webpack.js" "webpack": "bin/webpack.js"
@ -1850,9 +1845,9 @@
} }
}, },
"node_modules/webpack-sources": { "node_modules/webpack-sources": {
"version": "3.2.3", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {

View File

@ -9,7 +9,8 @@
], ],
"settings": { "settings": {
"prettier.semi": false, "prettier.semi": false,
"cloudcode.duetAI.project": "beepmill-code", "cloudcode.project": "beepmill-code",
"cloudcode.project": "beepmill-code" "geminicodeassist.project": "beepmill-code",
"typescript.tsdk": "product_inventory\\node_modules\\typescript\\lib"
} }
} }

View File

@ -43,37 +43,24 @@ export function columnOnEditHandler(e: GoogleAppsScript.Events.SheetsOnEdit) {
for (let row = e.range.getRow(); row <= e.range.getLastRow(); row++) { for (let row = e.range.getRow(); row <= e.range.getLastRow(); row++) {
console.log("row: " + row) console.log("row: " + row)
let updateString = "updating " + header + " on row " + row let updateString = "updating " + header + " on row " + row
switch (header) { let shopifyUpdateColumns = [
case "shopify_status": "shopify_status",
toastAndLog(updateString) "title",
updateProductToShopify(row) "product_type",
break "tags",
case "title": "description",
toastAndLog(updateString) "base_price",
updateProductToShopify(row) "original_price",
break "weight_grams",
case "product_type": "product_height_cm",
toastAndLog(updateString) "product_width_cm",
updateProductToShopify(row) "product_depth_cm"
break ]
case "tags": if (shopifyUpdateColumns.includes(header)) {
toastAndLog(updateString) // Accumulate changes for 30s before updating
updateProductToShopify(row) toastAndLog(updateString)
break updateProductToShopify(row)
case "description": break
toastAndLog(updateString)
updateProductToShopify(row)
break
case "price":
toastAndLog(updateString)
updateProductToShopify(row)
break
case "compare_at_price":
toastAndLog(updateString)
updateProductToShopify(row)
break
default:
continue
} }
toastAndLog("completed " + updateString) toastAndLog("completed " + updateString)
} }

View File

@ -5,22 +5,27 @@ import {
ShopifyProductsQuery, ShopifyProductsQuery,
ShopifyProductsResponse, ShopifyProductsResponse,
ShopifyProductSetInput, ShopifyProductSetInput,
ShopifyVariant, ShopifyProductVariant,
ShopifyProductSetQuery, ShopifyProductSetQuery,
ShopifyVariant,
VariantOptionValueInput, VariantOptionValueInput,
formatGqlForJSON, formatGqlForJSON,
} from "./shopifyApi" } from "./shopifyApi"
import * as shopify from 'shopify-admin-api-typings' import * as shopify from "shopify-admin-api-typings"
import { getCellRangeByColumnName, getRowByColumnValue } from "./sheetUtils" import {
getCellRangeByColumnName,
getRowByColumnValue,
vlookupByColumns,
} from "./sheetUtils"
import { Config } from "./config" import { Config } from "./config"
export class Product { export class Product {
shopify_id: string = "" shopify_id: string = ""
title: string = "" title: string = ""
style: string[] = [] style: string[] = []
tags: string = "" tags: string = ""
category: string = "" category: string = ""
ebay_category_id: string = ""
product_type: string = "" product_type: string = ""
description: string = "" description: string = ""
sku: string = "" sku: string = ""
@ -30,6 +35,9 @@ export class Product {
function: string = "" function: string = ""
type: string = "" type: string = ""
weight_grams: number = 0 weight_grams: number = 0
product_width_cm: number = 0
product_depth_cm: number = 0
product_height_cm: number = 0
photos: string = "" photos: string = ""
shopify_product: shopify.Product shopify_product: shopify.Product
shopify_default_variant_id: string = "" shopify_default_variant_id: string = ""
@ -110,10 +118,26 @@ export class Product {
) )
} }
ShopifyCategory(): string {
return vlookupByColumns(
"values",
"product_type",
this.product_type,
"shopify_category"
)
}
EbayCategory(): string {
return vlookupByColumns(
"values",
"product_type",
this.product_type,
"ebay_category_id"
)
}
ToShopifyProductSet() { ToShopifyProductSet() {
let sps = new ShopifyProductSetInput() let sps = new ShopifyProductSetInput()
//TODO: map category IDs
//sps.category = this.category
if (this.shopify_id != "") { if (this.shopify_id != "") {
sps.id = this.shopify_id sps.id = this.shopify_id
} }
@ -121,6 +145,10 @@ export class Product {
sps.status = this.shopify_status sps.status = this.shopify_status
} }
sps.productType = this.product_type sps.productType = this.product_type
let category = this.ShopifyCategory()
if (category !== "") {
sps.category = this.ShopifyCategory()
}
sps.tags = this.tags sps.tags = this.tags
sps.title = this.title sps.title = this.title
sps.descriptionHtml = this.description sps.descriptionHtml = this.description
@ -174,12 +202,136 @@ export class Product {
response = this.PublishToShopifyOnlineStore(shop) response = this.PublishToShopifyOnlineStore(shop)
console.log("UpdateShopifyProduct: setting defaults on inventory item") console.log("UpdateShopifyProduct: setting defaults on inventory item")
shop.SetInventoryItemDefaults(item, config) shop.SetInventoryItemDefaults(item, config)
if (this.weight_grams > 0) {
console.log("UpdateShopifyProduct: setting weight on inventory item")
shop.SetInventoryItemWeight(
item,
config,
this.weight_grams,
shopify.WeightUnit.GRAMS
)
}
if (newProduct) { if (newProduct) {
console.log("UpdateShopifyProduct: setting defaults on new product") console.log("UpdateShopifyProduct: setting defaults on new product")
console.log("UpdateShopifyProduct: adjusting inventory item quantity") console.log("UpdateShopifyProduct: adjusting inventory item quantity")
shop.UpdateInventoryItemQuantity(item, 1, config) shop.UpdateInventoryItemQuantity(item, 1, config)
console.log(JSON.stringify(response, null, 2)) console.log(JSON.stringify(response, null, 2))
} }
// update all metafields
this.UpdateAllMetafields(shop);
// create product photo folder
this.CreatePhotoFolder();
}
UpdateAllMetafields(shop: Shop) {
console.log("UpdateAllMetafields()")
if (!this.shopify_id) {
console.log("Cannot update metafields without a Shopify Product ID.")
return
}
const metafieldsToSet: shopify.MetafieldsSetInput[] = []
// eBay Category Metafield
if (this.product_type) {
this.ebay_category_id = this.EbayCategory()
if (this.ebay_category_id) {
metafieldsToSet.push({
key: "ebay_category_id",
namespace: "custom",
ownerId: this.shopify_id,
type: "single_line_text_field",
value: this.ebay_category_id.toString(),
})
} else {
console.log(
`No eBay category defined for product type '${this.product_type}'`
)
}
} else {
console.log("No product type set, skipping eBay category metafield.")
}
// Dimension Metafields
if (this.product_height_cm > 0) {
metafieldsToSet.push({
key: "product_height_cm",
namespace: "custom",
ownerId: this.shopify_id,
type: "dimension",
value: JSON.stringify({
value: this.product_height_cm,
unit: "cm",
}),
})
}
if (this.product_width_cm > 0) {
metafieldsToSet.push({
key: "product_width_cm",
namespace: "custom",
ownerId: this.shopify_id,
type: "dimension",
value: JSON.stringify({
value: this.product_width_cm,
unit: "cm",
}),
})
}
if (this.product_depth_cm > 0) {
metafieldsToSet.push({
key: "product_depth_cm",
namespace: "custom",
ownerId: this.shopify_id,
type: "dimension",
value: JSON.stringify({
value: this.product_depth_cm,
unit: "cm",
}),
})
}
if (metafieldsToSet.length === 0) {
console.log("No metafields to update.")
return
}
const query = /* GraphQL */ `
mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) {
metafieldsSet(metafields: $metafields) {
metafields {
id
key
namespace
value
}
userErrors {
field
message
code
}
}
}
`
const variables = {
metafields: metafieldsToSet,
}
const json = `{
"query": ${formatGqlForJSON(String(query))},
"variables": ${JSON.stringify(variables)}
}`
console.log("Setting metafields with query:\n" + json)
const response = shop.shopifyGraphQLAPI(JSON.parse(json))
console.log("metafieldsSet response: " + JSON.stringify(response, null, 2))
}
CreatePhotoFolder() {
console.log("Product.CreatePhotoFolder()");
createPhotoFolderForSku(new(Config), this.sku);
} }
PublishToShopifyOnlineStore(shop: Shop) { PublishToShopifyOnlineStore(shop: Shop) {
@ -226,3 +378,56 @@ export class Product {
// TODO: shopify_status // TODO: shopify_status
} }
} }
export function createPhotoFolderForSku(config: Config, sku: string) {
console.log(`createPhotoFolderForSku('${sku}')`)
if (!config.productPhotosFolderId) {
console.log(
"productPhotoFolderId not set in config. Skipping folder creation."
)
return
}
const productInventorySheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("product_inventory")
const row = getRowByColumnValue("product_inventory", "sku", sku)
if (!row) {
console.log(`SKU '${sku}' not found in sheet. Cannot create folder.`)
return
}
const photosCell = getCellRangeByColumnName(
productInventorySheet,
"photos",
row
)
const folderUrl = photosCell.getRichTextValue().getLinkUrl()
console.log(`Folder URL from cell: ${folderUrl}`)
if (folderUrl && folderUrl.includes("drive.google.com")) {
console.log(`Photo folder already exists: ${folderUrl}`)
return
} else {
console.log(`Creating photo folder for SKU: ${sku}`)
}
const parentFolder = DriveApp.getFolderById(config.productPhotosFolderId)
const folderName = sku
let newFolder: GoogleAppsScript.Drive.Folder
const existingFolders = parentFolder.getFoldersByName(folderName)
if (existingFolders.hasNext()) {
newFolder = existingFolders.next()
console.log(`Found existing photo folder: '${folderName}'`)
} else {
newFolder = parentFolder.createFolder(folderName)
console.log(`Created new photo folder: '${folderName}'`)
}
let url = newFolder.getUrl()
console.log(`Folder URL: ${url}`)
let linkValue = SpreadsheetApp.newRichTextValue()
.setText(folderName)
.setLinkUrl(url)
.build()
photosCell.setRichTextValue(linkValue)
}

View File

@ -1,56 +1,32 @@
import { createPhotoFolderForSku } from "./Product"
import { getColumnRichTextByName, getColumnValuesByName, toastAndLog } from "./sheetUtils"
import { Config } from "./config" import { Config } from "./config"
import {
getCellRangeByColumnName,
getColumnValuesByName,
toastAndLog,
} from "./sheetUtils"
export function createMissingPhotoFolders() { export function createMissingPhotoFolders() {
let ss = SpreadsheetApp.getActive() const ss = SpreadsheetApp.getActive()
let s = ss.getSheetByName("product_inventory") const s = ss.getSheetByName("product_inventory")
let config = new Config() if (!s) {
let photoParent = DriveApp.getFolderById(config.productPhotosFolderId) toastAndLog("Could not find 'product_inventory' sheet.")
return
}
let skus = getColumnValuesByName(s, "sku") let skus = getColumnValuesByName(s, "sku")
let photoLinks = getColumnValuesByName(s, "photos") let photos = getColumnRichTextByName(s, "photos")
let created: string[] = [] let config = new Config()
let folderItr = photoParent.getFolders() // Process rows backward, as that is where the missing folders are most likely to occur
let folderNames: string[] = [] for (let i = skus.length - 1; i >= 0; i--) {
console.log("getting list of existing folders...") const sku = String(skus[i][0])
while (folderItr.hasNext()) { if (!sku) {
let folder = folderItr.next()
folderNames.push(folder.getName())
}
console.log("existing folders: " + folderNames.join(", "))
for (let i = 0; i < skus.length; i++) {
let sku = String(skus[i][0])
let updateLink: boolean = false
if (null == sku || sku == "") {
continue continue
} }
if (folderNames.includes(sku)) { let folderUrl = photos[i][0].getLinkUrl()
console.log("folder '" + sku + "' already exists") if (folderUrl && folderUrl.includes("drive.google.com")) {
} else { console.log(`Photo folder already exists for SKU: ${sku}`)
console.log("creating folder '" + skus[i] + "'")
photoParent.createFolder(sku)
created.push(sku)
updateLink = true
}
// Update photos cell
if (photoLinks[i][0] != "" && !updateLink) {
continue continue
} }
console.log("updating photos cell for '" + sku + "'")
let photosCell = getCellRangeByColumnName(s, "photos", i + 2) createPhotoFolderForSku(config, sku)
let folder = photoParent.getFoldersByName(sku).next()
let url = folder.getUrl()
let linkValue = SpreadsheetApp.newRichTextValue()
.setText(sku)
.setLinkUrl(url)
.build()
photosCell.setRichTextValue(linkValue)
} }
toastAndLog("created " + created.length + " folders: " + created.join(", ")) toastAndLog("Finished creating missing photo folders.")
} }

View File

@ -1,6 +1,7 @@
/// <reference types="@types/google-apps-script" /> /// <reference types="@types/google-apps-script" />
import { onOpen } from "./onOpen" import { onOpen } from "./onOpen"
import { matchProductToShopifyOnEditHandler } from "./OnEditHandler"
import { getShopifyProducts } from "./shopifyApi" import { getShopifyProducts } from "./shopifyApi"
import { runShopifyOrders } from "./shopifyApi" import { runShopifyOrders } from "./shopifyApi"
import { import {
@ -13,6 +14,10 @@ import { createMissingPhotoFolders } from "./createMissingPhotoFolders"
import { reinstallTriggers } from "./triggers" import { reinstallTriggers } from "./triggers"
import { newSkuHandler } from "./newSku" import { newSkuHandler } from "./newSku"
import { columnOnEditHandler } from "./OnEditHandler" import { columnOnEditHandler } from "./OnEditHandler"
import {
onEditQueue,
processBatchedEdits
} from "./onEditQueue"
import { fillProductFromTemplate } from "./fillProductFromTemplate" import { fillProductFromTemplate } from "./fillProductFromTemplate"
// prettier-ignore // prettier-ignore
@ -24,6 +29,8 @@ import { fillProductFromTemplate } from "./fillProductFromTemplate"
;(global as any).matchProductToShopifyOnEditHandler = matchProductToShopifyOnEditHandler ;(global as any).matchProductToShopifyOnEditHandler = matchProductToShopifyOnEditHandler
;(global as any).updateShopifyProductHandler = updateShopifyProductHandler ;(global as any).updateShopifyProductHandler = updateShopifyProductHandler
;(global as any).columnOnEditHandler = columnOnEditHandler ;(global as any).columnOnEditHandler = columnOnEditHandler
;(global as any).onEditQueue = onEditQueue
;(global as any).processBatchedEdits = processBatchedEdits
;(global as any).reauthorizeScript = reauthorizeScript ;(global as any).reauthorizeScript = reauthorizeScript
;(global as any).reinstallTriggers = reinstallTriggers ;(global as any).reinstallTriggers = reinstallTriggers
;(global as any).newSkuHandler = newSkuHandler ;(global as any).newSkuHandler = newSkuHandler

View File

@ -1,3 +1,5 @@
import { createPhotoFolderForSku } from "./Product"
import { Config } from "./config"
import { import {
getColumnByName, getColumnByName,
getCellRangeByColumnName, getCellRangeByColumnName,
@ -5,6 +7,7 @@ import {
getColumnValuesByName, getColumnValuesByName,
} from "./sheetUtils" } from "./sheetUtils"
const LOCK_TIMEOUT_MS = 1000 * 10
export function newSkuHandler(e: GoogleAppsScript.Events.SheetsOnEdit) { export function newSkuHandler(e: GoogleAppsScript.Events.SheetsOnEdit) {
var sheet = SpreadsheetApp.getActive().getActiveSheet() var sheet = SpreadsheetApp.getActive().getActiveSheet()
@ -20,7 +23,19 @@ export function newSkuHandler(e: GoogleAppsScript.Events.SheetsOnEdit) {
console.log("new ID was not requested, returning") console.log("new ID was not requested, returning")
return return
} }
newSku(row) // Acquire a user lock to prevent multiple onEdit calls from clashing
const documentLock = LockService.getDocumentLock()
try {
const config = new (Config);
documentLock.waitLock(LOCK_TIMEOUT_MS)
const sku = newSku(row)
console.log("new sku: " + sku)
createPhotoFolderForSku(config, String(sku))
} catch (error) {
console.log("Error in newSkuHandler: " + error.message)
} finally {
documentLock.releaseLock()
}
} }
export function newSku(row: number) { export function newSku(row: number) {
@ -62,4 +77,6 @@ export function newSku(row: number) {
let newId = maxId + 1 let newId = maxId + 1
console.log("newId: " + newId) console.log("newId: " + newId)
idCell.setValue(newId) idCell.setValue(newId)
return `${skuPrefixCellValue}-${newId.toString().padStart(4, "0")}`
} }

119
src/onEditQueue.ts Normal file
View File

@ -0,0 +1,119 @@
import { getCellValueByColumnName } from "./sheetUtils"
import { Product } from "./Product"
import { Shop } from "./shopifyApi"
// --- Constants ---
const BATCH_INTERVAL_MS = 30 * 1000 // 30 seconds
const LOCK_TIMEOUT_MS = 10 * 1000 // 10 seconds for lock acquisition
const CACHE_KEY_EDITS = "pendingEdits"
const CACHE_KEY_LAST_EDIT_TIME = "lastEditTime"
const SCRIPT_PROPERTY_TRIGGER_SCHEDULED = "batchTriggerScheduled"
export function onEditQueue(e) {
const sheet = e.source.getActiveSheet()
if (sheet.getName() !== "product_inventory") {
console.log("skipping edit on sheet " + sheet.getName())
return
}
const range = e.range
const row = range.getRow()
const sku = getCellValueByColumnName(sheet, "sku", row)
if (!sku) {
console.log("No SKU found for row " + row)
return
}
// Make sure SKU conforms to expected patterns
if (sku.match(`\\?`) || sku.match(`n$`)) {
console.log("SKU is a placeholder ('?' or 'n...'), skipping batching.")
return
}
// Acquire a user lock to prevent multiple onEdit calls from clashing
const documentLock = LockService.getDocumentLock()
try {
documentLock.waitLock(LOCK_TIMEOUT_MS)
const scriptProperties = PropertiesService.getScriptProperties() // Shared cache for all users
// 1. Accumulate edits in cache
let pendingEdits = []
try {
pendingEdits = JSON.parse(
scriptProperties.getProperty(CACHE_KEY_EDITS) || "[]"
)
} catch (e) {
console.log("Cache corruption: " + e.message)
scriptProperties.setProperty(CACHE_KEY_EDITS, "[]")
}
const existingIndex = pendingEdits.findIndex((item) => item.sku === sku)
if (existingIndex !== -1) {
console.log("New edit on queued SKU '"+sku+"', resetting timer...")
pendingEdits[existingIndex].timestamp = Date.now()
} else {
console.log("New SKU '"+sku+"' added to queue.")
pendingEdits.push({ sku, timestamp: Date.now() })
}
scriptProperties.setProperty(CACHE_KEY_EDITS, JSON.stringify(pendingEdits))
} catch (error) {
console.log(
"Error in onEdit (lock acquisition or cache operation): " + error.message
)
} finally {
documentLock.releaseLock()
}
}
export function processBatchedEdits() {
const scriptLock = LockService.getScriptLock() // Use script lock for the processing function
try {
scriptLock.waitLock(LOCK_TIMEOUT_MS)
const scriptProperties = PropertiesService.getScriptProperties()
let pendingEdits = []
try {
const pendingEditsStr = scriptProperties.getProperty(CACHE_KEY_EDITS)
pendingEdits = pendingEditsStr ? JSON.parse(pendingEditsStr) : []
} catch (e) {
console.log("Cache corruption: " + e.message)
scriptProperties.setProperty(CACHE_KEY_EDITS, "[]")
}
console.log(`Total SKUs in queue: ${pendingEdits.length}`)
const now = Date.now()
const toProcess = pendingEdits.filter(
(edit) => now - edit.timestamp > BATCH_INTERVAL_MS
)
if (toProcess.length > 0) {
let shop = new Shop()
console.log(`Processing ${toProcess.length} SKUs...`)
toProcess.forEach((edit) => {
console.log(
`Processing SKU ${edit.sku}, Timestamp: ${new Date(edit.timestamp)}`
)
// Make sure SKU conforms to expected patterns
if (!edit.sku.match(/^\w+-\d{4}$/)) {
console.log(`SKU ${edit.sku} is not valid, skipping processing.`)
return
}
let p = new Product(edit.sku)
p.UpdateShopifyProduct(shop)
})
pendingEdits = pendingEdits.filter(
edit => !toProcess.some(p => p.sku === edit.sku)
);
scriptProperties.setProperty(CACHE_KEY_EDITS, JSON.stringify(pendingEdits));
console.log(`Processed ${toProcess.length} edits.`)
} else {
console.log("No pending edits to process.")
}
} catch (error) {
console.log(
"Error in processBatchedEdits (lock acquisition or processing): " +
error.message
)
} finally {
scriptLock.releaseLock()
}
}

View File

@ -16,7 +16,10 @@ export function productTemplate(row: number) {
"tags", "tags",
"base_price", "base_price",
"shipping", "shipping",
"weight (grams)", "weight_grams",
"product_width_cm",
"product_depth_cm",
"product_height_cm",
] ]
let productInventorySheet = let productInventorySheet =

View File

@ -50,6 +50,16 @@ export function getColumnValuesByName(
} }
} }
export function getColumnRichTextByName(
sheet: GoogleAppsScript.Spreadsheet.Sheet,
columnName: string
) {
let column = getColumnRangeByName(sheet, columnName)
if (column != null) {
return column.getRichTextValues()
}
}
export function vlookupByColumns( export function vlookupByColumns(
sheetName: string, sheetName: string,
searchColumn: string, searchColumn: string,

View File

@ -671,6 +671,43 @@ export class Shop {
return newItem return newItem
} }
SetInventoryItemWeight(item: shopify.InventoryItem, config: Config, weight: number, weight_unit: shopify.WeightUnit) {
let gql = /* GraphQL */ `
mutation inventoryItemUpdate($id: ID!, $input: InventoryItemInput!) {
inventoryItemUpdate(id: $id, input: $input) {
inventoryItem {
id
measurement {
weight {
value
unit
}
}
}
userErrors {
field
message
}
}
}
`
let variables = {
id: item.id,
input: {
measurement: {
weight: {
value: weight,
unit: weight_unit
}
}
},
}
let query = buildGqlQuery(gql, variables)
let response = this.shopifyGraphQLAPI(query)
let newItem: shopify.InventoryItem = response.content
return newItem
}
shopifyAPI(endpoint: string, query: {}, next = "") { shopifyAPI(endpoint: string, query: {}, next = "") {
var options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = { var options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
method: "get", method: "get",
@ -890,6 +927,8 @@ export class ShopifyVariant {
compareAtPrice?: number compareAtPrice?: number
barcode?: string barcode?: string
position?: number position?: number
metafields?: shopify.Metafield[]
inventory_item?: shopify.InventoryItemInput
nodes?: ShopifyProductVariant[] nodes?: ShopifyProductVariant[]
//TODO: support multiple options //TODO: support multiple options
optionValues: [{}] = [ optionValues: [{}] = [
@ -1016,6 +1055,7 @@ export class ShopifyProductSetInput {
title: string title: string
vendor: string vendor: string
variants: ShopifyVariant[] variants: ShopifyVariant[]
metafields: shopify.MetafieldInput[]
//TODO: Support multiple product options //TODO: Support multiple product options
productOptions: [{}] = [ productOptions: [{}] = [
{ {

View File

@ -10,5 +10,11 @@ export function reinstallTriggers() {
.forSpreadsheet(ss) .forSpreadsheet(ss)
.onEdit() .onEdit()
.create() .create()
ScriptApp.newTrigger("columnOnEditHandler").forSpreadsheet(ss).onEdit().create() // ScriptApp.newTrigger("columnOnEditHandler").forSpreadsheet(ss).onEdit().create()
// ScriptApp.newTrigger("onEditQueue").forSpreadsheet(ss).onEdit().create()
ScriptApp.newTrigger("onEditQueue").forSpreadsheet(ss).onEdit().create()
ScriptApp.newTrigger("processBatchedEdits")
.timeBased()
.everyMinutes(1)
.create()
} }