@globalbrain/sefirot 4.32.1 → 4.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client.d.ts CHANGED
@@ -1,14 +1,10 @@
1
1
  /// <reference types="vite/client" />
2
2
  /// <reference types="unplugin-icons/types/vue3" />
3
+ /// <reference path="shared.d.ts" />
3
4
 
4
5
  // this file contains public types which are exposed to external modules
5
6
 
6
7
  declare module 'v-calendar' {
7
- export * from 'v-calendar/dist/types/src/index.d.ts'
8
- export { default } from 'v-calendar/dist/types/src/index.d.ts'
9
- }
10
-
11
- interface NumberConstructor {
12
- isFinite(value: unknown): value is number
13
- isInteger(value: unknown): value is number
8
+ export type * from 'v-calendar/dist/types/src/index.d.ts'
9
+ export type { default } from 'v-calendar/dist/types/src/index.d.ts'
14
10
  }
package/config/nuxt.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { fileURLToPath } from 'node:url'
4
4
  import icons from 'unplugin-icons/nuxt'
5
- import { mergeConfig } from 'vite'
5
+ import * as vite from 'vite'
6
6
  import { baseConfig as baseViteConfig } from './vite.js'
7
7
 
8
8
  export const baseConfig = {
@@ -26,9 +26,27 @@ export const baseConfig = {
26
26
  plugins: baseViteConfig.plugins?.filter(
27
27
  (plugin) => plugin && 'name' in plugin && plugin.name !== 'unplugin-icons'
28
28
  )
29
+ },
30
+ nitro: {
31
+ rollupConfig: {
32
+ plugins: [{
33
+ name: 'custom:transpile-ts',
34
+ /**
35
+ * @param {string} code
36
+ * @param {string} id
37
+ */
38
+ transform(code, id) {
39
+ if (id.endsWith('.ts')) {
40
+ // @ts-ignore
41
+ if (vite.rolldownVersion) { return vite.transformWithOxc(code, id, { sourcemap: true }) }
42
+ return vite.transformWithEsbuild(code, id, { sourcemap: true, loader: 'ts' })
43
+ }
44
+ }
45
+ }]
46
+ }
29
47
  }
30
48
  }
31
49
 
32
50
  export function defineConfig(config = {}) {
33
- return mergeConfig(baseConfig, config)
51
+ return vite.mergeConfig(baseConfig, config)
34
52
  }
package/config/vite.js CHANGED
@@ -70,12 +70,13 @@ export const baseConfig = {
70
70
 
71
71
  optimizeDeps: {
72
72
  include: [
73
+ '@globalbrain/sefirot/dompurify',
73
74
  'dayjs',
74
75
  'dayjs/plugin/relativeTime',
75
76
  'dayjs/plugin/timezone',
76
77
  'dayjs/plugin/utc',
78
+ 'dompurify',
77
79
  'file-saver',
78
- 'isomorphic-dompurify',
79
80
  'markdown-it > argparse',
80
81
  'markdown-it > entities'
81
82
  ],
@@ -134,11 +134,11 @@ function onClick(): void {
134
134
  </span>
135
135
  </span>
136
136
 
137
- <transition name="fade">
137
+ <Transition name="fade">
138
138
  <span v-if="loading" key="loading" class="loader">
139
139
  <SSpinner class="loader-icon" />
140
140
  </span>
141
- </transition>
141
+ </Transition>
142
142
  </component>
143
143
  </SFragment>
144
144
  </template>
@@ -6,9 +6,9 @@ const snackbars = useSnackbars()
6
6
  </script>
7
7
 
8
8
  <template>
9
- <transition name="fade">
9
+ <Transition name="fade">
10
10
  <div v-if="snackbars.items.length" class="SSnackbars">
11
- <transition-group name="fade-up">
11
+ <TransitionGroup name="fade-up">
12
12
  <div v-for="item in snackbars.items" :key="item.id" class="item">
13
13
  <SSnackbar
14
14
  :id="item.id"
@@ -17,9 +17,9 @@ const snackbars = useSnackbars()
17
17
  :actions="item.actions"
18
18
  />
19
19
  </div>
20
- </transition-group>
20
+ </TransitionGroup>
21
21
  </div>
22
- </transition>
22
+ </Transition>
23
23
  </template>
24
24
 
25
25
  <style lang="postcss" scoped>
@@ -152,11 +152,11 @@ function stopDialogPositionListener() {
152
152
  <IconDotsThree class="icon" />
153
153
  </button>
154
154
 
155
- <transition name="fade">
155
+ <Transition name="fade">
156
156
  <div v-if="isOpen" ref="dialog" class="dialog" :style="{ top, left }">
157
157
  <SDropdown :sections="dropdown" />
158
158
  </div>
159
- </transition>
159
+ </Transition>
160
160
  </div>
161
161
 
162
162
  <div v-if="resizable" class="grip" @mousedown="grip" />
@@ -1,4 +1,4 @@
1
- import DOMPurify, { type Config } from 'isomorphic-dompurify'
1
+ import { type DOMPurifyConfig, type DOMPurifyI, createDompurify } from '@globalbrain/sefirot/dompurify'
2
2
  import MarkdownIt from 'markdown-it'
3
3
 
4
4
  export type UseMarkdown = (source: string, inline?: boolean) => string
@@ -70,31 +70,40 @@ export interface UseMarkdownOptions extends MarkdownItOptions {
70
70
  config?: (md: MarkdownIt) => void
71
71
  /** @default false */
72
72
  inline?: boolean
73
- domPurifyOptions?: Config
73
+ domPurifyInstance?: DOMPurifyI
74
+ domPurifyOptions?: DOMPurifyConfig
74
75
  }
75
76
 
76
77
  const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i
77
78
 
78
- DOMPurify.addHook('afterSanitizeAttributes', (node) => {
79
- if (node.tagName === 'A') {
80
- const target = node.getAttribute('target')
81
- if (target && target !== '_blank' && target !== '_self') {
82
- node.removeAttribute('target')
79
+ let DOMPurify: DOMPurifyI | undefined
80
+
81
+ export function getDomPurifySingleton(): DOMPurifyI {
82
+ if (DOMPurify) { return DOMPurify }
83
+ DOMPurify = createDompurify()
84
+ DOMPurify.addHook('afterSanitizeAttributes', (node) => {
85
+ if (node.tagName === 'A') {
86
+ const target = node.getAttribute('target')
87
+ if (target && target !== '_blank' && target !== '_self') {
88
+ node.removeAttribute('target')
89
+ }
90
+
91
+ const href = node.getAttribute('href')
92
+ if (href && EXTERNAL_URL_RE.test(href)) {
93
+ node.setAttribute('target', '_blank')
94
+ node.setAttribute('rel', 'noreferrer')
95
+ }
96
+
97
+ node.classList.add('SMarkdown-link')
83
98
  }
84
-
85
- const href = node.getAttribute('href')
86
- if (href && EXTERNAL_URL_RE.test(href)) {
87
- node.setAttribute('target', '_blank')
88
- node.setAttribute('rel', 'noreferrer')
89
- }
90
-
91
- node.classList.add('SMarkdown-link')
92
- }
93
- })
99
+ })
100
+ return DOMPurify
101
+ }
94
102
 
95
103
  export function useMarkdown({
96
104
  config,
97
105
  inline: _inline,
106
+ domPurifyInstance,
98
107
  domPurifyOptions,
99
108
  ...options
100
109
  }: UseMarkdownOptions = {}): UseMarkdown {
@@ -115,7 +124,7 @@ export function useMarkdown({
115
124
 
116
125
  return (source, inline = _inline) => {
117
126
  const html = inline ? md.renderInline(source) : md.render(source)
118
- return DOMPurify.sanitize(html, {
127
+ return (domPurifyInstance || getDomPurifySingleton()).sanitize(html, {
119
128
  USE_PROFILES: { html: true },
120
129
  ADD_ATTR: ['target'],
121
130
  ...domPurifyOptions
@@ -0,0 +1,5 @@
1
+ import dompurify from 'dompurify'
2
+
3
+ export function createDompurify() {
4
+ return dompurify(window)
5
+ }
@@ -0,0 +1,6 @@
1
+ // must be imported from `@globalbrain/sefirot/dompurify`
2
+ // otherwise conditional exports in package.json won't work
3
+
4
+ export declare function createDompurify(): import('dompurify').DOMPurify
5
+
6
+ export type { Config as DOMPurifyConfig, DOMPurify as DOMPurifyI } from 'dompurify'
@@ -0,0 +1,6 @@
1
+ import dompurify from 'dompurify'
2
+ import { JSDOM } from 'jsdom'
3
+
4
+ export function createDompurify() {
5
+ return dompurify(new JSDOM(`<!DOCTYPE html>`).window)
6
+ }
@@ -1,5 +1,5 @@
1
1
  export function maxTotalFileSize(value: unknown, size: string): boolean {
2
- if (!Array.isArray(value) || value.some((v) => !(v instanceof File))) { return false }
2
+ if (!Array.isArray(value) || !value.every((v) => v instanceof File)) { return false }
3
3
 
4
4
  const factor = /gb/i.test(size) ? 1e9 : /mb/i.test(size) ? 1e6 : /kb/i.test(size) ? 1e3 : 1
5
5
  const total = value.reduce((total, file) => total + file.size, 0)
package/package.json CHANGED
@@ -1,27 +1,50 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
- "type": "module",
4
- "version": "4.32.1",
5
- "packageManager": "pnpm@10.28.0",
3
+ "version": "4.34.0",
6
4
  "description": "Vue Components for Global Brain Design System.",
7
- "author": "Kia Ishii <ka.ishii@globalbrains.com>",
8
- "license": "MIT",
5
+ "keywords": [
6
+ "vue",
7
+ "vue3",
8
+ "components",
9
+ "design-system",
10
+ "ui-library",
11
+ "globalbrain"
12
+ ],
13
+ "homepage": "https://sefirot.globalbrains.com/",
9
14
  "repository": {
10
15
  "type": "git",
11
- "url": "git@github.com:globalbrain/sefirot.git"
16
+ "url": "git+https://github.com/globalbrain/sefirot.git"
12
17
  },
13
- "bugs": {
14
- "url": "https://github.com/globalbrain/sefirot/issues"
18
+ "license": "MIT",
19
+ "author": "Kia Ishii <ka.ishii@globalbrains.com>",
20
+ "type": "module",
21
+ "exports": {
22
+ "./client": {
23
+ "types": "./client.d.ts"
24
+ },
25
+ "./config/nuxt": {
26
+ "types": "./config/nuxt.d.ts",
27
+ "import": "./config/nuxt.js"
28
+ },
29
+ "./config/vite": {
30
+ "types": "./config/vite.d.ts",
31
+ "import": "./config/vite.js"
32
+ },
33
+ "./dompurify": {
34
+ "types": "./lib/dompurify/index.d.ts",
35
+ "browser": "./lib/dompurify/browser.js",
36
+ "default": "./lib/dompurify/node.js"
37
+ },
38
+ "./shared": {
39
+ "types": "./shared.d.ts"
40
+ },
41
+ "./*": "./*"
15
42
  },
16
- "keywords": [
17
- "sefirot",
18
- "vue",
19
- "vue component"
20
- ],
21
43
  "files": [
22
44
  "lib",
23
45
  "config",
24
- "client.d.ts"
46
+ "client.d.ts",
47
+ "shared.d.ts"
25
48
  ],
26
49
  "scripts": {
27
50
  "docs": "pnpm docs:dev",
@@ -49,7 +72,7 @@
49
72
  "@types/body-scroll-lock": "^3.1.2",
50
73
  "@types/lodash-es": "^4.17.12",
51
74
  "@types/markdown-it": "^14.1.2",
52
- "@vue/reactivity": "^3.5.26",
75
+ "@vue/reactivity": "^3.5.27",
53
76
  "@vuelidate/core": "^2.0.3",
54
77
  "@vuelidate/validators": "^2.0.4",
55
78
  "@vueuse/core": "^12 || ^13 || ^14",
@@ -63,26 +86,28 @@
63
86
  "postcss": "^8.5.6",
64
87
  "postcss-nested": "^7.0.2",
65
88
  "v-calendar": "3.0.1",
66
- "vue": "^3.5.26",
89
+ "vue": "^3.5.27",
67
90
  "vue-router": "^4.6.4"
68
91
  },
69
92
  "dependencies": {
70
- "@sentry/browser": "^10.33.0",
71
- "@sentry/vue": "^10.33.0",
93
+ "@sentry/browser": "^10.35.0",
94
+ "@sentry/vue": "^10.35.0",
72
95
  "@tanstack/vue-virtual": "3.0.0-beta.62",
73
96
  "@tinyhttp/content-disposition": "^2.2.2",
74
97
  "@tinyhttp/cookie": "^2.1.1",
98
+ "@total-typescript/ts-reset": "^0.6.1",
75
99
  "@types/d3": "^7.4.3",
76
100
  "@types/file-saver": "^2.0.7",
77
101
  "@types/qs": "^6.14.0",
78
102
  "d3": "^7.9.0",
103
+ "dompurify": "^3.3.1",
79
104
  "file-saver": "^2.0.5",
80
105
  "html2canvas": "^1.4.1",
81
- "isomorphic-dompurify": "^2.35.0",
106
+ "jsdom": "^27.4.0",
82
107
  "magic-string": "^0.30.21",
83
108
  "ofetch": "^1.5.1",
84
109
  "qs": "^6.14.1",
85
- "unplugin-icons": "^22.5.0"
110
+ "unplugin-icons": "^23.0.1"
86
111
  },
87
112
  "devDependencies": {
88
113
  "@globalbrain/eslint-config": "^2.1.0",
@@ -92,12 +117,13 @@
92
117
  "@popperjs/core": "^2.11.8",
93
118
  "@release-it/conventional-changelog": "^10.0.4",
94
119
  "@types/body-scroll-lock": "^3.1.2",
120
+ "@types/jsdom": "^27.0.0",
95
121
  "@types/lodash-es": "^4.17.12",
96
122
  "@types/markdown-it": "^14.1.2",
97
- "@types/node": "^25.0.7",
123
+ "@types/node": "^25.0.9",
98
124
  "@vitejs/plugin-vue": "^6.0.3",
99
125
  "@vitest/coverage-v8": "^3.2.4",
100
- "@vue/reactivity": "^3.5.26",
126
+ "@vue/reactivity": "^3.5.27",
101
127
  "@vue/test-utils": "^2.4.6",
102
128
  "@vuelidate/core": "^2.0.3",
103
129
  "@vuelidate/validators": "^2.0.4",
@@ -106,7 +132,7 @@
106
132
  "dayjs": "^1.11.19",
107
133
  "eslint": "^9.39.2",
108
134
  "fuse.js": "^7.1.0",
109
- "happy-dom": "^20.1.0",
135
+ "happy-dom": "^20.3.3",
110
136
  "histoire": "0.16.5",
111
137
  "lodash-es": "^4.17.22",
112
138
  "markdown-it": "^14.1.0",
@@ -121,8 +147,9 @@
121
147
  "vite": "^6.4.1",
122
148
  "vitepress": "^2.0.0-alpha.15",
123
149
  "vitest": "^3.2.4",
124
- "vue": "^3.5.26",
150
+ "vue": "^3.5.27",
125
151
  "vue-router": "^4.6.4",
126
152
  "vue-tsc": "^3.2.2"
127
- }
153
+ },
154
+ "packageManager": "pnpm@10.28.1"
128
155
  }
package/shared.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /// <reference types="@total-typescript/ts-reset/dom" />
2
+
3
+ interface NumberConstructor {
4
+ isFinite(value: unknown): value is number
5
+ isInteger(value: unknown): value is number
6
+ }