@kaspernj/api-maker 1.0.361 → 1.0.363

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": "@kaspernj/api-maker",
3
- "version": "1.0.361",
3
+ "version": "1.0.363",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "main": "index.js",
@@ -35,7 +35,7 @@
35
35
  "on-location-changed": ">= 1.0.10",
36
36
  "qs": ">= 6.9.3",
37
37
  "replaceall": ">= 0.1.6",
38
- "set-state-compare": "^1.0.41",
38
+ "set-state-compare": "^1.0.42",
39
39
  "spark-md5": "^3.0.2",
40
40
  "strftime": ">= 0.10.0",
41
41
  "uniqunize": "^1.0.1",
package/src/api.mjs CHANGED
@@ -4,6 +4,7 @@ import FormDataObjectizer from "form-data-objectizer"
4
4
  import Logger from "./logger.mjs"
5
5
  import qs from "qs"
6
6
  import SessionStatusUpdater from "./session-status-updater.mjs"
7
+ import urlEncode from "./url-encode.mjs"
7
8
 
8
9
  const logger = new Logger({name: "ApiMaker / Api"})
9
10
 
@@ -21,7 +22,7 @@ export default class Api {
21
22
  requestPath += path
22
23
 
23
24
  if (pathParams) {
24
- const pathParamsString = qs.stringify(pathParams, {arrayFormat: "brackets"})
25
+ const pathParamsString = qs.stringify(pathParams, {arrayFormat: "brackets", encoder: urlEncode})
25
26
  requestPath += `?${pathParamsString}`
26
27
  }
27
28
 
@@ -4,10 +4,10 @@ import {Input} from "../inputs/input"
4
4
  import InvalidFeedback from "./invalid-feedback"
5
5
  import Money from "../inputs/money"
6
6
  import PropTypes from "prop-types"
7
- import React from "react"
7
+ import {memo} from "react"
8
8
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
9
9
 
10
- const ApiMakerBootstrapInput = shapeComponent(class ApiMakerBootstrapInput extends ShapeComponent {
10
+ const ApiMakerBootstrapInput = memo(shapeComponent(class ApiMakerBootstrapInput extends ShapeComponent {
11
11
  static propTypes = {
12
12
  append: PropTypes.node,
13
13
  appendText: PropTypes.node,
@@ -167,6 +167,6 @@ const ApiMakerBootstrapInput = shapeComponent(class ApiMakerBootstrapInput exten
167
167
 
168
168
  return classNames.join(" ")
169
169
  }
170
- })
170
+ }))
171
171
 
172
172
  export default inputWrapper(ApiMakerBootstrapInput)
@@ -9,7 +9,7 @@ import ModelRow from "./live-table/model-row"
9
9
  import Paginate from "./paginate"
10
10
  import Params from "../params"
11
11
  import PropTypes from "prop-types"
12
- import React, {memo} from "react"
12
+ import {memo} from "react"
13
13
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
14
14
  import SortLink from "./sort-link"
15
15
 
@@ -3,10 +3,12 @@ import Link from "../link"
3
3
  import PropTypes from "prop-types"
4
4
  import propTypesExact from "prop-types-exact"
5
5
  import qs from "qs"
6
- import React from "react"
6
+ import {memo} from "react"
7
7
  import Result from "../result"
8
+ import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
9
+ import urlEncode from "../url-encode.mjs"
8
10
 
9
- export default class ApiMakerBootstrapPaginate extends React.PureComponent {
11
+ export default memo(shapeComponent(class ApiMakerBootstrapPaginate extends ShapeComponent {
10
12
  static propTypes = propTypesExact({
11
13
  result: PropTypes.oneOfType([
12
14
  instanceOfClassName("ApiMakerResult"),
@@ -14,8 +16,10 @@ export default class ApiMakerBootstrapPaginate extends React.PureComponent {
14
16
  ]).isRequired
15
17
  })
16
18
 
17
- state = {
18
- pages: this.pages()
19
+ setup() {
20
+ this.useStates({
21
+ pages: () => this.pages()
22
+ })
19
23
  }
20
24
 
21
25
  componentDidUpdate (prevProps) {
@@ -52,12 +56,13 @@ export default class ApiMakerBootstrapPaginate extends React.PureComponent {
52
56
  pagePath (pageNumber) {
53
57
  let pageKey = this.props.result.data.collection.queryArgs.pageKey
54
58
 
55
- if (!pageKey)
59
+ if (!pageKey) {
56
60
  pageKey = "page"
61
+ }
57
62
 
58
63
  const currentParams = qs.parse(globalThis.location.search.substr(1))
59
64
  currentParams[pageKey] = pageNumber
60
- const newParams = qs.stringify(currentParams)
65
+ const newParams = qs.stringify(currentParams, {encoder: urlEncode})
61
66
  const newPath = `${location.pathname}?${newParams}`
62
67
 
63
68
  return newPath
@@ -150,4 +155,4 @@ export default class ApiMakerBootstrapPaginate extends React.PureComponent {
150
155
  </>
151
156
  )
152
157
  }
153
- }
158
+ }))
@@ -3,6 +3,7 @@ import * as inflection from "inflection"
3
3
  import PropTypes from "prop-types"
4
4
  import qs from "qs"
5
5
  import React from "react"
6
+ import urlEncode from "../url-encode.mjs"
6
7
 
7
8
  import Link from "../link"
8
9
  import PureComponent from "set-state-compare/src/pure-component"
@@ -35,7 +36,7 @@ class ApiMakerBootstrapSortLink extends PureComponent {
35
36
 
36
37
  queryParams[searchKey] = JSON.stringify(qParams)
37
38
 
38
- const newParams = qs.stringify(queryParams)
39
+ const newParams = qs.stringify(queryParams, {encoder: urlEncode})
39
40
  const newPath = `${location.pathname}?${newParams}`
40
41
 
41
42
  return newPath
@@ -4,12 +4,12 @@ import EventUpdated from "../event-updated"
4
4
  import inputWrapper from "./input-wrapper"
5
5
  import Money from "./money"
6
6
  import PropTypes from "prop-types"
7
- import React, {useRef} from "react"
7
+ import {memo, useRef} from "react"
8
8
  import replaceall from "replaceall"
9
9
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
10
10
  import strftime from "strftime"
11
11
 
12
- const ApiMakerInputsInput = shapeComponent(class ApiMakerInputsInput extends ShapeComponent {
12
+ const ApiMakerInputsInput = memo(shapeComponent(class ApiMakerInputsInput extends ShapeComponent {
13
13
  static defaultProps = {
14
14
  autoRefresh: false,
15
15
  autoSubmit: false,
@@ -229,7 +229,7 @@ const ApiMakerInputsInput = shapeComponent(class ApiMakerInputsInput extends Sha
229
229
  if (this.props.inputProps.type == "file" && value == "")
230
230
  return true
231
231
  }
232
- })
232
+ }))
233
233
 
234
234
  export {ApiMakerInputsInput as Input}
235
235
  export default inputWrapper(ApiMakerInputsInput)
@@ -6,10 +6,10 @@ import * as inflection from "inflection"
6
6
  import MoneyFormatter from "../money-formatter"
7
7
  import PropTypes from "prop-types"
8
8
  import PropTypesExact from "prop-types-exact"
9
- import React, {useRef} from "react"
9
+ import {memo, useRef} from "react"
10
10
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
11
11
 
12
- export default shapeComponent(class ApiMakerInputsMoney extends ShapeComponent {
12
+ export default memo(shapeComponent(class ApiMakerInputsMoney extends ShapeComponent {
13
13
  static defaultProps = {
14
14
  disabled: false,
15
15
  showCurrencyOptions: true
@@ -183,4 +183,4 @@ export default shapeComponent(class ApiMakerInputsMoney extends ShapeComponent {
183
183
  if (this.props.onChange && oldCents != cents)
184
184
  this.props.onChange()
185
185
  }
186
- })
186
+ }))
package/src/params.mjs CHANGED
@@ -2,6 +2,7 @@ import config from "./config.mjs"
2
2
  import formSerialize from "form-serialize"
3
3
  import Incorporator from "incorporator"
4
4
  import qs from "qs"
5
+ import urlEncode from "./url-encode.mjs"
5
6
 
6
7
  export default class Params {
7
8
  static parse () {
@@ -17,7 +18,7 @@ export default class Params {
17
18
  }
18
19
 
19
20
  static withParams (params) {
20
- const newParams = qs.stringify(params)
21
+ const newParams = qs.stringify(params, {encoder: urlEncode})
21
22
  const newPath = `${location.pathname}?${newParams}`
22
23
 
23
24
  return newPath
@@ -25,7 +26,7 @@ export default class Params {
25
26
 
26
27
  static changeParams (given, opts = {}) {
27
28
  const params = Params.change(given)
28
- const newParams = qs.stringify(params)
29
+ const newParams = qs.stringify(params, {encoder: urlEncode})
29
30
  const newPath = `${location.pathname}?${newParams}`
30
31
  const appHistory = opts.appHistory || config.getHistory() || AppHistory
31
32
 
@@ -1,43 +1,10 @@
1
- import PropTypes from "prop-types"
2
- import PropTypesExact from "prop-types-exact"
3
- import React from "react"
1
+ import {memo} from "react"
2
+ import useResizeObserver from "./use-resize-observer.mjs"
4
3
 
5
- export default class ApiMakerResizeObserver extends React.PureComponent {
6
- static propTypes = PropTypesExact({
7
- element: PropTypes.instanceOf(Element),
8
- onResize: PropTypes.func.isRequired
9
- })
4
+ const ApiMakerResizeObserver = memo(({element, onResize}) => {
5
+ useResizeObserver(element, onResize)
10
6
 
11
- componentDidMount() {
12
- if (this.props.element) this.startObserve()
13
- }
7
+ return null
8
+ })
14
9
 
15
- componentDidUpdate(prevProps) {
16
- if (!prevProps.element && this.props.element) {
17
- this.startObserve()
18
- } else if (prevProps.element && !this.props.element) {
19
- this.endObserve()
20
- } else if (prevProps.element != this.props.element) {
21
- this.endObserve()
22
- this.startObserve()
23
- }
24
- }
25
-
26
- componentWillUnmount() {
27
- if (this.observer) this.endObserve()
28
- }
29
-
30
- startObserve() {
31
- this.observer = new ResizeObserver(this.props.onResize)
32
- this.observer.observe(this.props.element)
33
- }
34
-
35
- endObserve() {
36
- this.observer.disconnect()
37
- this.observer = null
38
- }
39
-
40
- render() {
41
- return null
42
- }
43
- }
10
+ export default ApiMakerResizeObserver
@@ -1,6 +1,7 @@
1
1
  import {dig, digg, digs} from "diggerize"
2
2
  import * as inflection from "inflection"
3
3
  import qs from "qs"
4
+ import urlEncode from "./url-encode.mjs"
4
5
 
5
6
  export default class ApiMakerRoutesNative {
6
7
  constructor ({getLocale}) {
@@ -111,7 +112,7 @@ export default class ApiMakerRoutesNative {
111
112
  .join("/")
112
113
 
113
114
  if (restOptions && Object.keys(restOptions).length > 0) {
114
- translatedRoute += `?${qs.stringify(restOptions)}`
115
+ translatedRoute += `?${qs.stringify(restOptions, {encoder: urlEncode})}`
115
116
  }
116
117
 
117
118
  if (url) return this.addHostToRoute({host, port, protocol, translatedRoute})
@@ -132,7 +133,7 @@ export default class ApiMakerRoutesNative {
132
133
  .join("/")
133
134
 
134
135
  if (restOptions && Object.keys(restOptions).length > 0) {
135
- translatedRoute += `?${qs.stringify(restOptions)}`
136
+ translatedRoute += `?${qs.stringify(restOptions, {encoder: urlEncode})}`
136
137
  }
137
138
 
138
139
  if (url) return this.addHostToRoute({host, port, protocol, translatedRoute})
@@ -3,7 +3,7 @@ import FilterForm from "./filter-form"
3
3
  import LoadSearchModal from "./load-search-modal"
4
4
  import SaveSearchModal from "./save-search-modal"
5
5
  import PropTypes from "prop-types"
6
- import React, {memo} from "react"
6
+ import {memo} from "react"
7
7
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
8
8
  import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
9
9
  import useQueryParams from "on-location-changed/src/use-query-params"
@@ -6,11 +6,12 @@ import * as inflection from "inflection"
6
6
  import Link from "../link"
7
7
  import MoneyFormatter from "../money-formatter"
8
8
  import PropTypes from "prop-types"
9
+ import {memo} from "react"
9
10
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
10
11
 
11
12
  const WorkerPluginsCheckbox = React.lazy(() => import("./worker-plugins-checkbox"))
12
13
 
13
- export default shapeComponent(class ApiMakerBootStrapLiveTableModelRow extends ShapeComponent {
14
+ export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow extends ShapeComponent {
14
15
  static propTypes = {
15
16
  cacheKey: PropTypes.string.isRequired,
16
17
  model: PropTypes.object.isRequired,
@@ -188,4 +189,4 @@ export default shapeComponent(class ApiMakerBootStrapLiveTableModelRow extends S
188
189
  throw new Error(`Unhandled type: ${apiMakerType}`)
189
190
  }
190
191
  }
191
- })
192
+ }))
@@ -4,12 +4,12 @@ import EventConnection from "../event-connection"
4
4
  import modelClassRequire from "../model-class-require.mjs"
5
5
  import PropTypes from "prop-types"
6
6
  import PropTypesExact from "prop-types-exact"
7
- import React, {useEffect} from "react"
7
+ import {memo, useEffect} from "react"
8
8
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component"
9
9
 
10
10
  const Workplace = modelClassRequire("Workplace")
11
11
 
12
- export default shapeComponent(class ApiMakerTableWorkerPluginsCheckbox extends ShapeComponent {
12
+ export default memo(shapeComponent(class ApiMakerTableWorkerPluginsCheckbox extends ShapeComponent {
13
13
  static propTypes = PropTypesExact({
14
14
  currentWorkplace: PropTypes.object,
15
15
  model: PropTypes.object.isRequired
@@ -102,4 +102,4 @@ export default shapeComponent(class ApiMakerTableWorkerPluginsCheckbox extends S
102
102
  this.setState({checked: false})
103
103
  }
104
104
  }
105
- })
105
+ }))
@@ -0,0 +1,19 @@
1
+ const replaces = {
2
+ " ": "+",
3
+ "&": "%26",
4
+ "#": "%23",
5
+ "/": "%2F",
6
+ "?": "%3F"
7
+ }
8
+
9
+ const urlEncode = (string) => {
10
+ return `${string}`.replaceAll(/( |&|#)/g, (character) => {
11
+ if (!(character in replaces)) {
12
+ throw new Error(`Didn't exist in replaces: "${character}"`)
13
+ }
14
+
15
+ return replaces[character]
16
+ })
17
+ }
18
+
19
+ export default urlEncode
@@ -0,0 +1,24 @@
1
+ import {useCallback, useMemo} from "react"
2
+ import useShape from "set-state-compare/src/use-shape.js"
3
+
4
+ const useResizeObserver = (element, callback) => {
5
+ const s = useShape({callback})
6
+ const onResize = useCallback((...args) => {
7
+ s.p.callback(...args)
8
+ }, [])
9
+ const observer = useMemo(() => new ResizeObserver(onResize), [])
10
+
11
+ useEffect(() => {
12
+ if (element) {
13
+ observer.observe(element)
14
+ }
15
+
16
+ return () => {
17
+ if (element) {
18
+ observer.disconnect()
19
+ }
20
+ }
21
+ }, [element])
22
+ }
23
+
24
+ export default useResizeObserver