diff --git a/ui/shared/query-string-encoding/__tests__/index.test.ts b/packages/query-string-encoding/__tests__/index.test.ts similarity index 98% rename from ui/shared/query-string-encoding/__tests__/index.test.ts rename to packages/query-string-encoding/__tests__/index.test.ts index 60c8c6fd58d..90dc83b8ffc 100644 --- a/ui/shared/query-string-encoding/__tests__/index.test.ts +++ b/packages/query-string-encoding/__tests__/index.test.ts @@ -17,7 +17,7 @@ */ import {toQueryString, encodeQueryString, decodeQueryString} from '../index' -import type {QueryParameterRecord} from '../index' +import type {QueryParameterRecord} from '../index.d' import $ from 'jquery' type EncodeQueryStringParams = Array> diff --git a/packages/query-string-encoding/index.d.ts b/packages/query-string-encoding/index.d.ts new file mode 100644 index 00000000000..cd049af5919 --- /dev/null +++ b/packages/query-string-encoding/index.d.ts @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +type QueryParameterElement = + | string + | number + | boolean + | null + | undefined + | (() => string) + | Array + | QueryParameterRecord + +export type QueryParameterRecord = {[k: string]: QueryParameterElement} + +export declare function toQueryString(params: QueryParameterRecord): string + +export declare function encodeQueryString( + unknownParams: + | Record[] + | Record +): string + +export declare function decodeQueryString(string: string): Record diff --git a/ui/shared/query-string-encoding/index.ts b/packages/query-string-encoding/index.js similarity index 80% rename from ui/shared/query-string-encoding/index.ts rename to packages/query-string-encoding/index.js index 13d175b0ed9..5d51c00ed6c 100644 --- a/ui/shared/query-string-encoding/index.ts +++ b/packages/query-string-encoding/index.js @@ -26,32 +26,20 @@ // ... so we have to do a lot of massaging with the params object before using it // So fun! -type QueryParameterElement = - | string - | number - | boolean - | null - | undefined - | (() => string) // n.b. for jQuery compatibility, this does not expect a generic return - | Array - | QueryParameterRecord - -export type QueryParameterRecord = {[k: string]: QueryParameterElement} - -export function toQueryString(params: QueryParameterRecord): string { - const paramsWithIndexes: Array<[k: string, v: string]> = [] +export function toQueryString(params) { + const paramsWithIndexes = [] // encode each key/value pair using encodeURIComponent, to ensure that each // key and value are properly encoded URI componeent strings. Otherwise, // URLSearchParams will convert blanks into '+' which is not what we want. - const asStringValue = (parms: URLSearchParams): string => { + const asStringValue = parms => { return Array.from(parms) .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`) .join('&') } // fix up the array/object indexes to match the PHP standard - const fixIndexes = (elt: [string, string]): [string, string] => [ + const fixIndexes = elt => [ elt[0] .replace(/\[\d+\]$/, '[]') .replace(/{/g, '[') @@ -59,7 +47,7 @@ export function toQueryString(params: QueryParameterRecord): string { elt[1], ] - function serialize(k: string, elt: QueryParameterElement, suffix: string): void { + function serialize(k, elt, suffix) { if (elt instanceof Function) { paramsWithIndexes.push([k + suffix, elt()]) } else if (elt instanceof Array) { @@ -85,22 +73,18 @@ export function toQueryString(params: QueryParameterRecord): string { // This is just to implement backward-compatibility from the old package. Almost // nothing uses it anyway and we recommend toQueryString() for new needs. // Need to be careful about duplicated keys, which have to be mapped into arrays. -export function encodeQueryString( - unknownParams: - | Record[] - | Record -): string { - let params: Record[] +export function encodeQueryString(unknownParams) { + let params if (Array.isArray(unknownParams)) { params = unknownParams } else if (typeof unknownParams === 'object') { - params = [unknownParams as Record] + params = [unknownParams] } else { throw new TypeError('encodeQueryString() expects an array or object') } - const realParms: QueryParameterRecord = {} + const realParms = {} params.forEach(p => { const k = Object.keys(p)[0] const m = k.match(/(.+)\[\]/) @@ -130,7 +114,7 @@ export function encodeQueryString( // in terms of how things like foo[]=1&foo[]=2 would be decoded. But it doesn't // seem like any current usage cares about that kind of thing. -export function decodeQueryString(string: string) { +export function decodeQueryString(string) { return string .split('&') .map(pair => pair.split('=')) diff --git a/packages/query-string-encoding/package.json b/packages/query-string-encoding/package.json new file mode 100644 index 00000000000..caa9d8c4f55 --- /dev/null +++ b/packages/query-string-encoding/package.json @@ -0,0 +1,7 @@ +{ + "name": "@instructure/query-string-encoding", + "private": true, + "version": "1.0.0", + "author": "neme", + "main": "./index.js" +} diff --git a/ui/features/account_admin_tools/react/BouncedEmailsView.jsx b/ui/features/account_admin_tools/react/BouncedEmailsView.jsx index 839ba58d988..1eb5d058437 100644 --- a/ui/features/account_admin_tools/react/BouncedEmailsView.jsx +++ b/ui/features/account_admin_tools/react/BouncedEmailsView.jsx @@ -31,7 +31,7 @@ import doFetchApi from '@canvas/do-fetch-api-effect' import CanvasDateInput from '@canvas/datetime/react/components/DateInput' import FriendlyDatetime from '@canvas/datetime/react/components/FriendlyDatetime' import * as tz from '@instructure/moment-utils' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' const I18n = useI18nScope('bounced_emails') diff --git a/ui/features/announcements/react/apiClient.js b/ui/features/announcements/react/apiClient.js index 1b3e318c4dc..750c8f82a43 100644 --- a/ui/features/announcements/react/apiClient.js +++ b/ui/features/announcements/react/apiClient.js @@ -17,7 +17,7 @@ */ import axios from '@canvas/axios' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' import makePromisePool from '@canvas/make-promise-pool' const MAX_CONCURRENT_REQS = 5 diff --git a/ui/features/assignment_index/backbone/views/CreateAssignmentView.js b/ui/features/assignment_index/backbone/views/CreateAssignmentView.js index c2b5a658902..5a442eee7c0 100644 --- a/ui/features/assignment_index/backbone/views/CreateAssignmentView.js +++ b/ui/features/assignment_index/backbone/views/CreateAssignmentView.js @@ -39,7 +39,7 @@ import { isMidnight, } from '@instructure/moment-utils' import * as tz from '@instructure/moment-utils' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' import {renderDatetimeField} from '@canvas/datetime/jquery/DatetimeField' const I18n = useI18nScope('CreateAssignmentView') diff --git a/ui/features/calendar/backbone/views/EditAssignmentDetails.js b/ui/features/calendar/backbone/views/EditAssignmentDetails.js index c72a7582506..94b793f83d8 100644 --- a/ui/features/calendar/backbone/views/EditAssignmentDetails.js +++ b/ui/features/calendar/backbone/views/EditAssignmentDetails.js @@ -37,7 +37,7 @@ import fcUtil from '@canvas/calendar/jquery/fcUtil' import '@canvas/jquery/jquery.instructure_forms' import '@canvas/jquery/jquery.instructure_misc_helpers' import '../../fcMomentHandlebarsHelpers' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' import {renderDatetimeField} from '@canvas/datetime/jquery/DatetimeField' const I18n = useI18nScope('calendar') diff --git a/ui/features/calendar/jquery/ShowEventDetailsDialog.jsx b/ui/features/calendar/jquery/ShowEventDetailsDialog.jsx index 4c33f78f1de..89f194db7a0 100644 --- a/ui/features/calendar/jquery/ShowEventDetailsDialog.jsx +++ b/ui/features/calendar/jquery/ShowEventDetailsDialog.jsx @@ -33,7 +33,7 @@ import reservationOverLimitDialog from '../jst/reservationOverLimitDialog.handle import MessageParticipantsDialog from '@canvas/calendar/jquery/MessageParticipantsDialog' import preventDefault from '@canvas/util/preventDefault' import axios from '@canvas/axios' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' import {publish} from 'jquery-tinypubsub' import '@canvas/jquery/jquery.ajaxJSON' import '@canvas/jquery/jquery.instructure_misc_helpers' diff --git a/ui/features/calendar/jquery/index.js b/ui/features/calendar/jquery/index.js index 06a00a49db6..48cc83fce6d 100644 --- a/ui/features/calendar/jquery/index.js +++ b/ui/features/calendar/jquery/index.js @@ -24,7 +24,7 @@ import {useScope as useI18nScope} from '@canvas/i18n' import $ from 'jquery' import {map, defaults, filter, omit, each, has, last, includes} from 'lodash' import * as tz from '@instructure/moment-utils' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' import moment from 'moment' import {showFlashAlert} from '@canvas/alerts/react/FlashAlert' import decodeFromHex from '@canvas/util/decodeFromHex' diff --git a/ui/features/calendar/react/CalendarEventDetailsForm.jsx b/ui/features/calendar/react/CalendarEventDetailsForm.jsx index 94e631f941f..b194f6809c2 100644 --- a/ui/features/calendar/react/CalendarEventDetailsForm.jsx +++ b/ui/features/calendar/react/CalendarEventDetailsForm.jsx @@ -47,7 +47,7 @@ import { } from '@canvas/calendar/react/RecurringEvents/FrequencyPicker/utils' import {renderUpdateCalendarEventDialog} from '@canvas/calendar/react/RecurringEvents/UpdateCalendarEventDialog' import FrequencyPicker from '@canvas/calendar/react/RecurringEvents/FrequencyPicker/FrequencyPicker' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' const I18n = useI18nScope('calendar.edit_calendar_event') diff --git a/ui/features/conferences/backbone/views/EditConferenceView.js b/ui/features/conferences/backbone/views/EditConferenceView.js index fe30b0466ff..56fca499900 100644 --- a/ui/features/conferences/backbone/views/EditConferenceView.js +++ b/ui/features/conferences/backbone/views/EditConferenceView.js @@ -30,7 +30,7 @@ import userSettingOptionsTemplate from '../../jst/userSettingOptions.handlebars' import authenticity_token from '@canvas/authenticity-token' import numberHelper from '@canvas/i18n/numberHelper' import '@canvas/jquery/jquery.instructure_forms' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' import {renderDatetimeField} from '@canvas/datetime/jquery/DatetimeField' const I18n = useI18nScope('conferences') diff --git a/ui/features/content_migrations/backbone/views/subviews/CourseFindSelectView.js b/ui/features/content_migrations/backbone/views/subviews/CourseFindSelectView.js index 5c5408cc6e9..4f93ac6443f 100644 --- a/ui/features/content_migrations/backbone/views/subviews/CourseFindSelectView.js +++ b/ui/features/content_migrations/backbone/views/subviews/CourseFindSelectView.js @@ -28,7 +28,7 @@ import '@canvas/jquery/jquery.ajaxJSON' import '@canvas/jquery/jquery.disableWhileLoading' import 'jqueryui/menu' import 'jqueryui/autocomplete' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' const I18n = useI18nScope('content_migrations') diff --git a/ui/features/conversations/react/ConversationStatusFilter.jsx b/ui/features/conversations/react/ConversationStatusFilter.jsx index bf8b6fda322..02c906a83bd 100644 --- a/ui/features/conversations/react/ConversationStatusFilter.jsx +++ b/ui/features/conversations/react/ConversationStatusFilter.jsx @@ -17,7 +17,7 @@ */ import Backbone from '@canvas/backbone' -import {decodeQueryString} from '@canvas/query-string-encoding' +import {decodeQueryString} from '@instructure/query-string-encoding' import {FormField} from '@instructure/ui-form-field' import {useScope as useI18nScope} from '@canvas/i18n' import PropTypes from 'prop-types' diff --git a/ui/features/inbox/react/containers/CanvasInbox.jsx b/ui/features/inbox/react/containers/CanvasInbox.jsx index dd4028b8f6c..5a9bceeafd7 100644 --- a/ui/features/inbox/react/containers/CanvasInbox.jsx +++ b/ui/features/inbox/react/containers/CanvasInbox.jsx @@ -38,7 +38,7 @@ import { USER_INBOX_LABELS_QUERY, VIEWABLE_SUBMISSIONS_QUERY, } from '../../graphql/Queries' -import {decodeQueryString} from '@canvas/query-string-encoding' +import {decodeQueryString} from '@instructure/query-string-encoding' import {responsiveQuerySizes} from '../../util/utils' import {Flex} from '@instructure/ui-flex' diff --git a/ui/shared/do-fetch-api-effect/index.ts b/ui/shared/do-fetch-api-effect/index.ts index 1ae0ed5045a..b277b8d24ff 100644 --- a/ui/shared/do-fetch-api-effect/index.ts +++ b/ui/shared/do-fetch-api-effect/index.ts @@ -20,8 +20,8 @@ import getCookie from '@instructure/get-cookie' import parseLinkHeader, {type Links} from '@canvas/parse-link-header' import {defaultFetchOptions} from '@canvas/util/xhr' -import {toQueryString} from '@canvas/query-string-encoding' -import type {QueryParameterRecord} from '@canvas/query-string-encoding' +import {toQueryString} from '@instructure/query-string-encoding' +import type {QueryParameterRecord} from '@instructure/query-string-encoding/index.d' import z from 'zod' type RequestCredentials = 'include' | 'omit' | 'same-origin' diff --git a/ui/shared/groups/backbone/collections/ContextGroupCollection.js b/ui/shared/groups/backbone/collections/ContextGroupCollection.js index 1c4e1710ba1..9bedfe0a97f 100644 --- a/ui/shared/groups/backbone/collections/ContextGroupCollection.js +++ b/ui/shared/groups/backbone/collections/ContextGroupCollection.js @@ -19,7 +19,7 @@ import PaginatedCollection from '@canvas/pagination/backbone/collections/PaginatedCollection' import Group from '../models/Group' import natcompare from '@canvas/util/natcompare' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' export default class ContextGroupCollection extends PaginatedCollection { comparator = (x, y) => diff --git a/ui/shared/groups/backbone/collections/GroupUserCollection.js b/ui/shared/groups/backbone/collections/GroupUserCollection.js index f38874183f4..36af01e29a6 100644 --- a/ui/shared/groups/backbone/collections/GroupUserCollection.js +++ b/ui/shared/groups/backbone/collections/GroupUserCollection.js @@ -24,7 +24,7 @@ import $ from 'jquery' import PaginatedCollection from '@canvas/pagination/backbone/collections/PaginatedCollection' import GroupUser from '../models/GroupUser' import h from '@instructure/html-escape' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' const I18n = useI18nScope('GroupUserCollection') diff --git a/ui/shared/media-comments/jquery/kalturaAnalytics.js b/ui/shared/media-comments/jquery/kalturaAnalytics.js index 9600362cab7..826a98d8a2f 100644 --- a/ui/shared/media-comments/jquery/kalturaAnalytics.js +++ b/ui/shared/media-comments/jquery/kalturaAnalytics.js @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Affero General Public License along // with this program. If not, see . -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' import $ from 'jquery' import 'jquery.cookie' import {clone, throttle} from 'lodash' diff --git a/ui/shared/query-string-encoding/package.json b/ui/shared/query-string-encoding/package.json deleted file mode 100644 index 45f1a181e6d..00000000000 --- a/ui/shared/query-string-encoding/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "@canvas/query-string-encoding", - "private": true, - "version": "1.0.0", - "author": "neme", - "main": "./index.ts" -} diff --git a/ui/shared/quiz-legacy-client-apps/environment.js b/ui/shared/quiz-legacy-client-apps/environment.js index 60b52a23365..e4cc9ac4f31 100644 --- a/ui/shared/quiz-legacy-client-apps/environment.js +++ b/ui/shared/quiz-legacy-client-apps/environment.js @@ -16,7 +16,7 @@ * with this program. If not, see . */ -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' /** * @class Common.Core.Environment diff --git a/ui/shared/select-content-dialog/stores/ObjectStore.ts b/ui/shared/select-content-dialog/stores/ObjectStore.ts index ac44401e193..80c0d558bfa 100644 --- a/ui/shared/select-content-dialog/stores/ObjectStore.ts +++ b/ui/shared/select-content-dialog/stores/ObjectStore.ts @@ -21,7 +21,7 @@ import {clone} from 'lodash' import createStore, {type CanvasStore} from '@canvas/backbone/createStore' import parseLinkHeader from 'link-header-parsing/parseLinkHeaderFromXHR' import '@canvas/rails-flash-notifications' -import {encodeQueryString} from '@canvas/query-string-encoding' +import {encodeQueryString} from '@instructure/query-string-encoding' const initialStoreState = { links: {},