@kudoai/chatgpt.js 3.8.0 → 3.8.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kudoai/chatgpt.js",
3
- "version": "3.8.0",
3
+ "version": "3.8.2",
4
4
  "description": "Client-side JavaScript library for ChatGPT",
5
5
  "author": {
6
6
  "name": "KudoAI & contributors",
@@ -9,10 +9,16 @@
9
9
  },
10
10
  "homepage": "https://chatgpt.js.org",
11
11
  "license": "MIT",
12
- "funding": {
13
- "type": "github",
14
- "url": "http://github.com/sponsors/KudoAI"
15
- },
12
+ "funding": [
13
+ {
14
+ "type": "github",
15
+ "url": "http://github.com/sponsors/KudoAI"
16
+ },
17
+ {
18
+ "type": "paypal",
19
+ "url": "http://paypal.biz/kudoai"
20
+ }
21
+ ],
16
22
  "browser": "chatgpt.js",
17
23
  "files": [
18
24
  "chatgpt.js",
@@ -68,17 +74,16 @@
68
74
  "bugs": "https://github.com/KudoAI/chatgpt.js/issues",
69
75
  "devDependencies": {
70
76
  "@adamlui/minify.js": "^1.8.6",
71
- "@adamlui/scss-to-css": "^1.10.32",
72
- "@eslint/css": "^0.7.0",
73
- "@eslint/json": "^0.12.0",
74
- "@eslint/markdown": "^6.4.0",
75
- "@html-eslint/eslint-plugin": "^0.39.0",
76
- "@html-eslint/parser": "^0.39.0",
77
- "@stylistic/eslint-plugin-js": "^4.2.0",
78
- "docsify-cli": "^4.4.4",
79
- "eslint": "^9.25.1",
80
- "eslint-plugin-import": "^2.31.0",
81
- "eslint-plugin-regexp": "^2.7.0",
77
+ "@adamlui/scss-to-css": "^1.10.36",
78
+ "@eslint/css": "^0.10.0",
79
+ "@eslint/json": "^0.13.1",
80
+ "@eslint/markdown": "^7.1.0",
81
+ "@html-eslint/eslint-plugin": "^0.43.1",
82
+ "@html-eslint/parser": "^0.43.0",
83
+ "@stylistic/eslint-plugin": "^5.2.2",
84
+ "eslint": "^9.32.0",
85
+ "eslint-plugin-import": "^2.32.0",
86
+ "eslint-plugin-regexp": "^2.9.0",
82
87
  "eslint-plugin-yml": "^1.18.0",
83
88
  "get-port": "^7.1.0",
84
89
  "husky": "^9.1.7"
@@ -1,34 +1,40 @@
1
- // Requires lib/dom.js + app
1
+ // Requires lib/dom.js
2
2
 
3
3
  window.icons = {
4
- import(deps) { Object.assign(this.imports ||= {}, deps) },
5
4
 
6
- create(name, { size = 16, width, height, ...additionalAttrs } = {}) {
7
- const iconData = icons[name],
8
- iconAttrs = { width: width || size, height: height || size, ...additionalAttrs }
9
- if (iconData.type == 'svg') {
10
- const svg = dom.create.svgElem('svg', { viewBox: iconData.viewBox, ...iconAttrs })
11
- iconData.elems.forEach(([tag, attrs]) => svg.append(dom.create.svgElem(tag, attrs)))
12
- return svg
13
- } else // img w/ src
14
- return dom.create.elem('img', { src: iconData.src, ...iconAttrs })
5
+ create({ key, size = 18, width, height, ...otherAttrs }) {
6
+ if (!key) return console.error('Option \'key\' required by icons.create()')
7
+ const icon = {
8
+ data: this[key], attrs: { width: width || size, height: height || size, class: key, ...otherAttrs }}
9
+ if (icon.data?.svg) { // return <svg>
10
+ icon.svg = dom.create.svgElem('svg', { ...icon.data.svg, ...icon.attrs })
11
+ ;(function create(elems) {
12
+ return elems.map(elem => {
13
+ const [tag, attrs] = Object.entries(elem)[0], svgElem = dom.create.svgElem(tag, attrs)
14
+ if (attrs.elems) svgElem.append(...create(attrs.elems)) // recursively create() sub-elems
15
+ return svgElem
16
+ })
17
+ })(icon.data.elems).forEach(elem => icon.svg.append(elem))
18
+ return icon.svg
19
+ } else if (icon.data?.src) // return <img> w/ src
20
+ return dom.create.elem('img', { src: icon.data.src, ...icon.attrs })
21
+ else
22
+ return console.error(`No <svg|src> data found for key ${key}`)
15
23
  },
16
24
 
17
- caretDown: {
18
- type: 'svg', viewBox: '0 0 24 24',
19
- elems: [[ 'path', { d: 'm0 6.4 12 12 12-12z' }]]
25
+ caretDown: { svg: { viewBox: '0 0 24 24' }, elems: [{ path: { d: 'm0 6.4 12 12 12-12z' }}]},
26
+
27
+ open: {
28
+ svg: { viewBox: '0 0 512 512' },
29
+ elems: [{ path: { transform: 'translate(85.333333, 64)',
30
+ d: 'M128,63.999444 L128,106.666444 L42.6666667,106.666667 L42.6666667,320 L256,320 L256,234.666444 L298.666,234.666444 L298.666667,362.666667 L4.26325641e-14,362.666667 L4.26325641e-14,64 L128,63.999444 Z M362.666667,1.42108547e-14 L362.666667,170.666667 L320,170.666667 L320,72.835 L143.084945,249.751611 L112.915055,219.581722 L289.83,42.666 L192,42.6666667 L192,1.42108547e-14 L362.666667,1.42108547e-14 Z' }}]
20
31
  },
21
32
 
22
33
  plus: {
23
- type: 'svg', viewBox: '0 0 1024 1024',
24
- elems: [
25
- [ 'path', { d: 'M899.901 600.38H600.728v299.173c0 74.383-179.503 74.383-179.503 0V600.38H122.051c-74.384 0-74.384-179.503 0-179.503h299.173V121.703c0-74.384 179.503-74.384 179.503 0v299.174H899.9c74.385 0 74.385 179.503.001 179.503z' }]
26
- ]
34
+ svg: { viewBox: '0 0 1024 1024' },
35
+ elems: [{ path: { d: 'M899.901 600.38H600.728v299.173c0 74.383-179.503 74.383-179.503 0V600.38H122.051c-74.384 0-74.384-179.503 0-179.503h299.173V121.703c0-74.384 179.503-74.384 179.503 0v299.174H899.9c74.385 0 74.385 179.503.001 179.503z' }}]
27
36
  },
28
37
 
29
38
  questionMark: {
30
- type: 'png',
31
- get src() { return `${icons.imports.app.urls.assetHost.replace(
32
- '@latest', '@00e245b')}/images/icons/question-mark/icon16.png` }
33
- }
39
+ src: 'https://cdn.jsdelivr.net/gh/KudoAI/chatgpt.js-chrome-starter@8a59f80/images/icons/question-mark/icon16.png' }
34
40
  };
@@ -1,13 +1,12 @@
1
- // Requires lib/chatgpt.js + lib/dom.js + app + env
1
+ // Requires lib/<chatgpt|dom>.js + app + env
2
2
 
3
3
  window.modals = {
4
- import(deps) { Object.assign(this.imports ||= {}, deps) },
5
4
 
6
5
  stack: [], // of types of undismissed modals
7
- get class() { return `${this.imports.app.cssPrefix}-modal` },
6
+ get class() { return `${app.cssPrefix}-modal` },
8
7
 
9
8
  about() {
10
- const { app, env: { ui: { scheme }, browser: { isPortrait }}} = this.imports
9
+ const { ui: { scheme }, browser: { isPortrait }} = env
11
10
 
12
11
  // Show modal
13
12
  const labelStyles = 'text-transform: uppercase ; font-size: 17px ; font-weight: bold ;'
@@ -15,17 +14,20 @@ window.modals = {
15
14
  const aboutModal = this.alert(
16
15
  `${app.symbol} ${chrome.runtime.getManifest().name}`, // title
17
16
  `<span style="${labelStyles}">🧠 Author:</span> `
18
- + `<a href="${app.author.url}">${this.imports.app.author.name}</a> `
17
+ + `<a href="${app.author.url}">${app.author.name}</a> `
19
18
  + `& <a href="${app.urls.contributors}">contributors</a>\n`
20
19
  + `<span style="${labelStyles}">🏷️ Version:</span> `
21
20
  + `<span class="about-em">${app.version}</span>\n`
22
21
  + `<span style="${labelStyles}">📜 Open source code:</span> `
23
22
  + `<a href="${app.urls.gitHub}" target="_blank" rel="nopener">`
24
23
  + app.urls.gitHub + '</a>\n'
24
+ + `<span style="${labelStyles}">🚀 Latest changes:</span> `
25
+ + `<a href="${app.urls.gitHub}/commits" target="_blank" rel="nopener">`
26
+ + `${app.urls.gitHub}/commits</a>\n`
25
27
  + `<span style="${labelStyles}">⚡ Powered by:</span> `
26
- + `<a href="${app.urls.chatgptJS}" target="_blank" rel="noopener">chatgpt.js</a>`,
28
+ + `<a href="${app.urls.chatgptjs}" target="_blank" rel="noopener">chatgpt.js</a>`,
27
29
  [ function getSupport(){}, function rateUs(){}, function moreAiExtensions(){} ], // button labels
28
- '', 656 // modal width
30
+ '', 747 // modal width
29
31
  )
30
32
 
31
33
  // Format text
@@ -43,9 +45,9 @@ window.modals = {
43
45
  // Replace buttons w/ clones that don't dismiss modal
44
46
  btn.replaceWith(btn = btn.cloneNode(true))
45
47
  btn.onclick = () => this.safeWinOpen(
46
- btn.textContent == 'Get Support' ? `${modals.imports.app.urls.gitHub}/issues`
47
- : btn.textContent == 'Rate Us' ? `${modals.imports.app.urls.gitHub}/discussions`
48
- : modals.imports.app.urls.relatedExtensions
48
+ btn.textContent == 'Get Support' ? `${app.urls.gitHub}/issues`
49
+ : btn.textContent == 'Rate Us' ? `${app.urls.gitHub}/discussions`
50
+ : app.urls.relatedExtensions
49
51
  )
50
52
 
51
53
  // Prepend emoji
@@ -104,9 +106,9 @@ window.modals = {
104
106
  safeWinOpen(url) { open(url, '_blank', 'noopener') }, // to prevent backdoor vulnerabilities
105
107
 
106
108
  stylize() {
107
- const { env: { ui: { scheme }, browser: { isMobile }}} = this.imports
109
+ const { ui: { scheme }, browser: { isMobile }} = env
108
110
  if (!this.styles) document.head.append(this.styles = dom.create.elem('style'))
109
- this.styles.innerText = (
111
+ this.styles.textContent = (
110
112
  `.${this.class} {` // modals
111
113
  + 'user-select: none ; -webkit-user-select: none ; -moz-user-select: none ; -ms-user-select: none ;'
112
114
  + 'font-family: -apple-system, system-ui, BlinkMacSystemFont, Segoe UI, Roboto,'
@@ -4,19 +4,15 @@
4
4
  (async () => {
5
5
 
6
6
  // Import JS resources
7
- for (const resource of ['components/modals.js', 'lib/chatgpt.js', 'lib/dom.js', 'lib/settings.js'])
7
+ for (const resource of ['components/modals.js', 'lib/chatgpt.js', 'lib/dom.js', 'lib/settings.js', 'lib/ui.js'])
8
8
  await import(chrome.runtime.getURL(resource))
9
9
 
10
10
  // Init ENV context
11
- const env = { browser: { isMobile: chatgpt.browser.isMobile() }, ui: { scheme: getScheme() }}
11
+ window.env = { browser: { isMobile: chatgpt.browser.isMobile() }, ui: { scheme: ui.getScheme() }}
12
12
  env.browser.isPortrait = env.browser.isMobile && (window.innerWidth < window.innerHeight)
13
13
 
14
14
  // Import APP data
15
- const { app } = await chrome.storage.local.get('app')
16
-
17
- // Export DEPENDENCIES to imported resources
18
- dom.import({ env }) // for env.ui.scheme
19
- modals.import({ app, env }) // for app data + env.<browser|ui> flags
15
+ ;({ app: window.app } = await chrome.storage.local.get('app'))
20
16
 
21
17
  chrome.runtime.onMessage.addListener(({ action, options }) => { // from service-worker.js + popup/index.html
22
18
  ({
@@ -24,7 +20,7 @@
24
20
  alert: () => modals.alert(...['title', 'msg', 'btns', 'checkbox', 'width'].map(arg => options[arg])),
25
21
  showAbout: () => { config.skipAlert = true ; chatgpt.isLoaded().then(() => modals.open('about')) },
26
22
  syncConfigToUI: () => syncConfigToUI(options)
27
- }[action]?.())
23
+ }[action]?.() || console.warn(`Chome msg listener warning: "${action}"`))
28
24
  })
29
25
 
30
26
  // Init SETTINGS
@@ -40,7 +36,7 @@
40
36
  if (foundState) msg = msg.replace(foundState, '')
41
37
 
42
38
  // Show notification
43
- chatgpt.notify(`${app.symbol} ${msg}`, pos, notifDuration, shadow || env.ui.scheme == 'dark' ? '' : 'shadow')
39
+ chatgpt.notify(`${app.symbol} ${msg}`, pos, notifDuration, shadow || env.ui.scheme == 'light')
44
40
  const notif = document.querySelector('.chatgpt-notif:last-child')
45
41
 
46
42
  // Append styled state word
@@ -74,23 +70,18 @@
74
70
  }
75
71
  }
76
72
 
77
- function getScheme() {
78
- return document.documentElement.className
79
- || (window.matchMedia?.('(prefers-color-scheme: dark)')?.matches ? 'dark' : 'light')
80
- }
81
-
82
73
  // Run MAIN routine
83
74
 
84
75
  chatgpt.printAllFunctions() // to console
85
76
 
86
77
  // CHILL a bit if your hacks depend on delayed DOM content
87
78
  await chatgpt.isLoaded()
88
- await new Promise(resolve => setTimeout(resolve, 500)); // sleep .5s
79
+ await new Promise(resolve => setTimeout(resolve, 500)) // sleep .5s
89
80
 
90
81
  // Add RISING PARTICLES styles for modals
91
- ['gray', 'white'].forEach(color => document.head.append(
82
+ ;['gray', 'white'].forEach(color => document.head.append(
92
83
  dom.create.elem('link', { rel: 'stylesheet',
93
- href: `https://cdn.jsdelivr.net/gh/adamlui/ai-web-extensions@727feff/assets/styles/rising-particles/dist/${
84
+ href: `https://cdn.jsdelivr.net/gh/adamlui/ai-web-extensions@71695ca/assets/styles/rising-particles/dist/${
94
85
  color}.min.css`
95
86
  })))
96
87
 
@@ -111,7 +102,7 @@
111
102
  window.matchMedia('(prefers-color-scheme: dark)').addEventListener( // for browser/system scheme pref changes
112
103
  'change', () => requestAnimationFrame(handleSchemePrefChange))
113
104
  function handleSchemePrefChange() {
114
- const displayedScheme = getScheme()
105
+ const displayedScheme = ui.getScheme()
115
106
  if (env.ui.scheme != displayedScheme) { env.ui.scheme = displayedScheme ; modals.stylize() }
116
107
  }
117
108