diff --git a/app/javascript/application.js b/app/javascript/application.js index 5a209c92..b28d0bb2 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -100,8 +100,7 @@ window.customElements.define('template-builder', class extends HTMLElement { withFormula: this.dataset.withFormula === 'true', withConditions: this.dataset.withConditions === 'true', currencies: (this.dataset.currencies || '').split(',').filter(Boolean), - acceptFileTypes: this.dataset.acceptFileTypes, - isDirectUpload: this.dataset.isDirectUpload === 'true' + acceptFileTypes: this.dataset.acceptFileTypes }) this.app.mount(this.appElem) diff --git a/app/javascript/elements/file_dropzone.js b/app/javascript/elements/file_dropzone.js index 7511da06..d8fbb116 100644 --- a/app/javascript/elements/file_dropzone.js +++ b/app/javascript/elements/file_dropzone.js @@ -9,10 +9,6 @@ export default actionable(targetable(class extends HTMLElement { ] connectedCallback () { - if (this.dataset.isDirectUpload === 'true') { - import('@rails/activestorage') - } - this.addEventListener('drop', this.onDrop) this.addEventListener('dragover', (e) => e.preventDefault()) @@ -48,61 +44,11 @@ export default actionable(targetable(class extends HTMLElement { this.classList.toggle('opacity-50') } - async uploadFiles (files) { + uploadFiles () { this.toggleLoading() - if (this.dataset.isDirectUpload === 'true') { - const { DirectUpload } = await import('@rails/activestorage') - - await Promise.all( - Array.from(files).map(async (file) => { - const upload = new DirectUpload( - file, - '/direct_uploads', - this.input - ) - - return new Promise((resolve, reject) => { - upload.create((error, blob) => { - if (error) { - console.error(error) - - return reject(error) - } else { - return resolve(blob) - } - }) - }).catch((error) => { - console.error(error) - }) - }) - ).then((blobs) => { - if (this.dataset.submitOnUpload) { - this.querySelectorAll('[name="blob_signed_ids[]"]').forEach((e) => e.remove()) - } - - blobs.forEach((blob) => { - const input = document.createElement('input') - - input.type = 'hidden' - input.name = 'blob_signed_ids[]' - input.value = blob.signed_id - - this.append(input) - }) - - if (this.dataset.submitOnUpload === 'true') { - this.closest('form').querySelector('button[type="submit"]').click() - } - }).finally(() => { - if (this.dataset.submitOnUpload !== 'true') { - this.toggleLoading() - } - }) - } else { - if (this.dataset.submitOnUpload) { - this.closest('form').querySelector('button[type="submit"]').click() - } + if (this.dataset.submitOnUpload) { + this.closest('form').querySelector('button[type="submit"]').click() } } })) diff --git a/app/javascript/form.js b/app/javascript/form.js index 6647188e..2bfd3c5a 100644 --- a/app/javascript/form.js +++ b/app/javascript/form.js @@ -11,7 +11,6 @@ window.customElements.define('submission-form', class extends HTMLElement { this.app = createApp(Form, { submitter: JSON.parse(this.dataset.submitter), canSendEmail: this.dataset.canSendEmail === 'true', - isDirectUpload: this.dataset.isDirectUpload === 'true', goToLast: this.dataset.goToLast === 'true', isDemo: this.dataset.isDemo === 'true', attribution: this.dataset.attribution !== 'false', diff --git a/app/javascript/submission_form/attachment_step.vue b/app/javascript/submission_form/attachment_step.vue index 8636f31d..284d0c44 100644 --- a/app/javascript/submission_form/attachment_step.vue +++ b/app/javascript/submission_form/attachment_step.vue @@ -51,7 +51,6 @@ @@ -86,11 +85,6 @@ export default { required: false, default: () => ({}) }, - isDirectUpload: { - type: Boolean, - required: true, - default: false - }, modelValue: { type: Array, required: false, diff --git a/app/javascript/submission_form/dropzone.vue b/app/javascript/submission_form/dropzone.vue index 5557ec86..e5a70385 100644 --- a/app/javascript/submission_form/dropzone.vue +++ b/app/javascript/submission_form/dropzone.vue @@ -70,11 +70,6 @@ export default { required: false, default: '*/*' }, - isDirectUpload: { - type: Boolean, - required: true, - default: false - }, multiple: { type: Boolean, required: false, @@ -92,11 +87,6 @@ export default { return 'el' + Math.random().toString(32).split('.')[1] } }, - mounted () { - if (this.isDirectUpload) { - import('@rails/activestorage') - } - }, methods: { onDropFiles (e) { this.uploadFiles(e.dataTransfer.files) @@ -113,72 +103,25 @@ export default { async uploadFiles (files) { this.isLoading = true - if (this.isDirectUpload) { - const { DirectUpload } = await import('@rails/activestorage') + return await Promise.all( + Array.from(files).map((file) => { + const formData = new FormData() - const blobs = await Promise.all( - Array.from(files).map(async (file) => { - const upload = new DirectUpload( - file, - '/direct_uploads', - this.$refs.input - ) + formData.append('file', file) + formData.append('submitter_slug', this.submitterSlug) + formData.append('name', 'attachments') - return new Promise((resolve, reject) => { - upload.create((error, blob) => { - if (error) { - console.error(error) - - return reject(error) - } else { - return resolve(blob) - } - }) - }).catch((error) => { - console.error(error) - }) + return fetch(this.baseUrl + '/api/attachments', { + method: 'POST', + body: formData + }).then(resp => resp.json()).then((data) => { + return data }) - ) - - return await Promise.all( - blobs.map((blob) => { - return fetch(this.baseUrl + '/api/attachments', { - method: 'POST', - body: JSON.stringify({ - name: 'attachments', - blob_signed_id: blob.signed_id, - submitter_slug: this.submitterSlug - }), - headers: { 'Content-Type': 'application/json' } - }).then(resp => resp.json()).then((data) => { - return data - }) - })).then((result) => { - this.$emit('upload', result) - }).finally(() => { - this.isLoading = false - }) - } else { - return await Promise.all( - Array.from(files).map((file) => { - const formData = new FormData() - - formData.append('file', file) - formData.append('submitter_slug', this.submitterSlug) - formData.append('name', 'attachments') - - return fetch(this.baseUrl + '/api/attachments', { - method: 'POST', - body: formData - }).then(resp => resp.json()).then((data) => { - return data - }) - })).then((result) => { - this.$emit('upload', result) - }).finally(() => { - this.isLoading = false - }) - } + })).then((result) => { + this.$emit('upload', result) + }).finally(() => { + this.isLoading = false + }) } } } diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index e19aa731..58e7f452 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -306,7 +306,6 @@ :key="currentField.uuid" v-model="values[currentField.uuid]" :field="currentField" - :is-direct-upload="isDirectUpload" :attachments-index="attachmentsIndex" :submitter-slug="submitterSlug" :show-field-names="showFieldNames" @@ -319,7 +318,6 @@ v-model="values[currentField.uuid]" :field="currentField" :previous-value="previousSignatureValueFor(currentField)" - :is-direct-upload="isDirectUpload" :with-typed-signature="withTypedSignature" :attachments-index="attachmentsIndex" :submitter-slug="submitterSlug" @@ -335,7 +333,6 @@ v-model="values[currentField.uuid]" :field="currentField" :previous-value="previousInitialsValue" - :is-direct-upload="isDirectUpload" :attachments-index="attachmentsIndex" :show-field-names="showFieldNames" :submitter-slug="submitterSlug" @@ -348,7 +345,6 @@ v-else-if="currentField.type === 'file'" :key="currentField.uuid" v-model="values[currentField.uuid]" - :is-direct-upload="isDirectUpload" :field="currentField" :attachments-index="attachmentsIndex" :submitter-slug="submitterSlug" @@ -578,11 +574,6 @@ export default { required: false, default: '' }, - isDirectUpload: { - type: Boolean, - required: false, - default: false - }, allowToSkip: { type: Boolean, required: false, diff --git a/app/javascript/submission_form/image_step.vue b/app/javascript/submission_form/image_step.vue index 63cefa1b..d68e7cf0 100644 --- a/app/javascript/submission_form/image_step.vue +++ b/app/javascript/submission_form/image_step.vue @@ -38,7 +38,6 @@ :message="`${t('upload')} ${field.name || t('image')}${field.required ? '' : ` (${t('optional')})`}`" :submitter-slug="submitterSlug" :accept="'image/*'" - :is-direct-upload="isDirectUpload" @upload="onImageUpload" /> @@ -62,11 +61,6 @@ export default { type: Object, required: true }, - isDirectUpload: { - type: Boolean, - required: true, - default: false - }, showFieldNames: { type: Boolean, required: false, diff --git a/app/javascript/submission_form/initials_step.vue b/app/javascript/submission_form/initials_step.vue index 274a7401..72bf97e6 100644 --- a/app/javascript/submission_form/initials_step.vue +++ b/app/javascript/submission_form/initials_step.vue @@ -152,11 +152,6 @@ export default { required: false, default: true }, - isDirectUpload: { - type: Boolean, - required: true, - default: false - }, attachmentsIndex: { type: Object, required: false, @@ -202,10 +197,6 @@ export default { this.$refs.textInput?.focus() }) - if (this.isDirectUpload) { - import('@rails/activestorage') - } - if (this.$refs.canvas) { this.pad = new SignaturePad(this.$refs.canvas) @@ -293,45 +284,21 @@ export default { cropCanvasAndExportToPNG(this.$refs.canvas).then(async (blob) => { const file = new File([blob], 'initials.png', { type: 'image/png' }) - if (this.isDirectUpload) { - const { DirectUpload } = await import('@rails/activestorage') + const formData = new FormData() - new DirectUpload( - file, - '/direct_uploads' - ).create((_error, data) => { - fetch(this.baseUrl + '/api/attachments', { - method: 'POST', - body: JSON.stringify({ - submitter_slug: this.submitterSlug, - blob_signed_id: data.signed_id, - name: 'attachments' - }), - headers: { 'Content-Type': 'application/json' } - }).then((resp) => resp.json()).then((attachment) => { - this.$emit('update:model-value', attachment.uuid) - this.$emit('attached', attachment) + formData.append('file', file) + formData.append('submitter_slug', this.submitterSlug) + formData.append('name', 'attachments') - return resolve(attachment) - }) - }) - } else { - const formData = new FormData() + return fetch(this.baseUrl + '/api/attachments', { + method: 'POST', + body: formData + }).then((resp) => resp.json()).then((attachment) => { + this.$emit('attached', attachment) + this.$emit('update:model-value', attachment.uuid) - formData.append('file', file) - formData.append('submitter_slug', this.submitterSlug) - formData.append('name', 'attachments') - - return fetch(this.baseUrl + '/api/attachments', { - method: 'POST', - body: formData - }).then((resp) => resp.json()).then((attachment) => { - this.$emit('attached', attachment) - this.$emit('update:model-value', attachment.uuid) - - return resolve(attachment) - }) - } + return resolve(attachment) + }) }) }) } diff --git a/app/javascript/submission_form/signature_step.vue b/app/javascript/submission_form/signature_step.vue index c9644f99..25215c39 100644 --- a/app/javascript/submission_form/signature_step.vue +++ b/app/javascript/submission_form/signature_step.vue @@ -176,11 +176,6 @@ export default { required: false, default: true }, - isDirectUpload: { - type: Boolean, - required: true, - default: false - }, withTypedSignature: { type: Boolean, required: false, @@ -230,10 +225,6 @@ export default { } }) - if (this.isDirectUpload) { - import('@rails/activestorage') - } - if (this.$refs.canvas) { this.pad = new SignaturePad(this.$refs.canvas) @@ -390,45 +381,21 @@ export default { cropCanvasAndExportToPNG(this.$refs.canvas, { errorOnTooSmall: true }).then(async (blob) => { const file = new File([blob], 'signature.png', { type: 'image/png' }) - if (this.isDirectUpload) { - const { DirectUpload } = await import('@rails/activestorage') - - new DirectUpload( - file, - '/direct_uploads' - ).create((_error, data) => { - fetch(this.baseUrl + '/api/attachments', { - method: 'POST', - body: JSON.stringify({ - submitter_slug: this.submitterSlug, - blob_signed_id: data.signed_id, - name: 'attachments' - }), - headers: { 'Content-Type': 'application/json' } - }).then((resp) => resp.json()).then((attachment) => { - this.$emit('update:model-value', attachment.uuid) - this.$emit('attached', attachment) - - return resolve(attachment) - }) - }) - } else { - const formData = new FormData() - - formData.append('file', file) - formData.append('submitter_slug', this.submitterSlug) - formData.append('name', 'attachments') - - return fetch(this.baseUrl + '/api/attachments', { - method: 'POST', - body: formData - }).then((resp) => resp.json()).then((attachment) => { - this.$emit('attached', attachment) - this.$emit('update:model-value', attachment.uuid) - - return resolve(attachment) - }) - } + const formData = new FormData() + + formData.append('file', file) + formData.append('submitter_slug', this.submitterSlug) + formData.append('name', 'attachments') + + return fetch(this.baseUrl + '/api/attachments', { + method: 'POST', + body: formData + }).then((resp) => resp.json()).then((attachment) => { + this.$emit('attached', attachment) + this.$emit('update:model-value', attachment.uuid) + + return resolve(attachment) + }) }).catch((error) => { return reject(error) }) diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index 88f7551d..b0bea84a 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -115,7 +115,6 @@ :with-replace-button="withUploadButton" :editable="editable" :template="template" - :is-direct-upload="isDirectUpload" @scroll-to="scrollIntoDocument(item)" @remove="onDocumentRemove" @replace="onDocumentReplace" @@ -131,7 +130,6 @@ v-if="sortedDocuments.length && editable && withUploadButton" :accept-file-types="acceptFileTypes" :template-id="template.id" - :is-direct-upload="isDirectUpload" @success="updateFromUpload" /> @@ -148,7 +146,6 @@ v-if="!sortedDocuments.length && withUploadButton" :template-id="template.id" :accept-file-types="acceptFileTypes" - :is-direct-upload="isDirectUpload" @success="updateFromUpload" /> @@ -180,7 +177,6 @@ :with-replace-button="withUploadButton" :document="document" :template="template" - :is-direct-upload="isDirectUpload" class="pb-2 mb-2 border-b border-base-300 border-dashed" @remove="onDocumentRemove" @replace="onDocumentReplace" @@ -196,7 +192,6 @@ @@ -345,11 +340,6 @@ export default { type: Object, required: true }, - isDirectUpload: { - type: Boolean, - required: false, - default: false - }, i18n: { type: Object, required: false, diff --git a/app/javascript/template_builder/controls.vue b/app/javascript/template_builder/controls.vue index 8a51b781..1a1991e0 100644 --- a/app/javascript/template_builder/controls.vue +++ b/app/javascript/template_builder/controls.vue @@ -8,7 +8,6 @@ /> parseInt(a.filename) - parseInt(b.filename))[0] } }, - mounted () { - if (this.isDirectUpload) { - import('@rails/activestorage') - } - }, methods: { upload: Upload.methods.upload, onUpdateName (value) { diff --git a/app/javascript/template_builder/replace.vue b/app/javascript/template_builder/replace.vue index dd2471eb..6a893711 100644 --- a/app/javascript/template_builder/replace.vue +++ b/app/javascript/template_builder/replace.vue @@ -36,11 +36,6 @@ export default { type: String, required: false, default: 'image/*, application/pdf' - }, - isDirectUpload: { - type: Boolean, - required: true, - default: false } }, emits: ['success'], @@ -64,11 +59,6 @@ export default { } } }, - mounted () { - if (this.isDirectUpload) { - import('@rails/activestorage') - } - }, methods: { upload: Upload.methods.upload } diff --git a/app/javascript/template_builder/upload.vue b/app/javascript/template_builder/upload.vue index da96ed71..3a14c742 100644 --- a/app/javascript/template_builder/upload.vue +++ b/app/javascript/template_builder/upload.vue @@ -60,11 +60,6 @@ export default { type: String, required: false, default: 'image/*, application/pdf' - }, - isDirectUpload: { - type: Boolean, - required: true, - default: false } }, emits: ['success'], @@ -79,112 +74,43 @@ export default { return 'el' + Math.random().toString(32).split('.')[1] } }, - mounted () { - if (this.isDirectUpload) { - import('@rails/activestorage') - } - }, methods: { async upload () { this.isLoading = true - if (this.isDirectUpload) { - const { DirectUpload } = await import('@rails/activestorage') - - const blobs = await Promise.all( - Array.from(this.$refs.input.files).map(async (file) => { - const upload = new DirectUpload( - file, - '/direct_uploads', - this.$refs.input - ) + this.baseFetch(`/templates/${this.templateId}/documents`, { + method: 'POST', + body: new FormData(this.$refs.form) + }).then((resp) => { + if (resp.ok) { + resp.json().then((data) => { + this.$emit('success', data) + this.$refs.input.value = '' + }) + } else if (resp.status === 422) { + resp.json().then((data) => { + if (data.error === 'PDF encrypted') { + const formData = new FormData(this.$refs.form) - return new Promise((resolve, reject) => { - upload.create((error, blob) => { - if (error) { - console.error(error) + formData.append('password', prompt('Enter PDF password')) - return reject(error) + this.baseFetch(`/templates/${this.templateId}/documents`, { + method: 'POST', + body: formData + }).then(async (resp) => { + if (resp.ok) { + this.$emit('success', await resp.json()) + this.$refs.input.value = '' } else { - return resolve(blob) + alert('Wrong password') } }) - }).catch((error) => { - console.error(error) - }) + } }) - ).finally(() => { - this.isLoading = false - }) - - this.isProcessing = true - - this.baseFetch(`/templates/${this.templateId}/documents`, { - method: 'POST', - body: JSON.stringify({ blobs }), - headers: { 'Content-Type': 'application/json' } - }).then((resp) => { - if (resp.ok) { - resp.json().then((data) => { - this.$emit('success', data) - this.$refs.input.value = '' - }) - } else if (resp.status === 422) { - resp.json().then((data) => { - if (data.error === 'PDF encrypted') { - this.baseFetch(`/templates/${this.templateId}/documents`, { - method: 'POST', - body: JSON.stringify({ blobs, password: prompt('Enter PDF password') }), - headers: { 'Content-Type': 'application/json' } - }).then(async (resp) => { - if (resp.ok) { - this.$emit('success', await resp.json()) - this.$refs.input.value = '' - } else { - alert('Wrong password') - } - }) - } - }) - } - }).finally(() => { - this.isProcessing = false - }) - } else { - this.baseFetch(`/templates/${this.templateId}/documents`, { - method: 'POST', - body: new FormData(this.$refs.form) - }).then((resp) => { - if (resp.ok) { - resp.json().then((data) => { - this.$emit('success', data) - this.$refs.input.value = '' - }) - } else if (resp.status === 422) { - resp.json().then((data) => { - if (data.error === 'PDF encrypted') { - const formData = new FormData(this.$refs.form) - - formData.append('password', prompt('Enter PDF password')) - - this.baseFetch(`/templates/${this.templateId}/documents`, { - method: 'POST', - body: formData - }).then(async (resp) => { - if (resp.ok) { - this.$emit('success', await resp.json()) - this.$refs.input.value = '' - } else { - alert('Wrong password') - } - }) - } - }) - } - }).finally(() => { - this.isLoading = false - }) - } + } + }).finally(() => { + this.isLoading = false + }) } } } diff --git a/app/views/esign_settings/show.html.erb b/app/views/esign_settings/show.html.erb index 85f58b2e..2f2a4171 100644 --- a/app/views/esign_settings/show.html.erb +++ b/app/views/esign_settings/show.html.erb @@ -15,7 +15,7 @@ Analyzing... <% end %> - + diff --git a/app/views/submit_form/_submission_form.html.erb b/app/views/submit_form/_submission_form.html.erb index e998d9e0..0e1d8820 100644 --- a/app/views/submit_form/_submission_form.html.erb +++ b/app/views/submit_form/_submission_form.html.erb @@ -1,4 +1,4 @@ <% data_attachments = attachments_index.values.select { |e| e.record_id == submitter.id }.to_json(only: %i[uuid], methods: %i[url filename content_type]) %> <% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %> <% configs = Submitters::FormConfigs.call(submitter) %> - + diff --git a/app/views/templates/edit.html.erb b/app/views/templates/edit.html.erb index 31cae956..32d18f89 100644 --- a/app/views/templates/edit.html.erb +++ b/app/views/templates/edit.html.erb @@ -1 +1 @@ - + diff --git a/app/views/templates_preview/show.html.erb b/app/views/templates_preview/show.html.erb index 10be9fc5..c0608228 100644 --- a/app/views/templates_preview/show.html.erb +++ b/app/views/templates_preview/show.html.erb @@ -1 +1 @@ - + diff --git a/app/views/user_signatures/edit.html.erb b/app/views/user_signatures/edit.html.erb index c8a824dd..cd60e4be 100644 --- a/app/views/user_signatures/edit.html.erb +++ b/app/views/user_signatures/edit.html.erb @@ -26,7 +26,7 @@ <%= form_for @user_config, url: user_signature_path, method: :put, data: { turbo_frame: :_top }, html: { autocomplete: :off, enctype: 'multipart/form-data' } do |f| %> - + diff --git a/lib/templates/create_attachments.rb b/lib/templates/create_attachments.rb index a635ca41..655da62c 100644 --- a/lib/templates/create_attachments.rb +++ b/lib/templates/create_attachments.rb @@ -43,11 +43,7 @@ module Templates end def find_or_create_blobs(params) - blobs = params[:blobs]&.map do |attrs| - ActiveStorage::Blob.find_signed(attrs[:signed_id]) - end - - blobs || params[:files].map do |file| + params[:files].map do |file| data = file.read if file.content_type == PDF_CONTENT_TYPE diff --git a/package.json b/package.json index 1101812f..045554d7 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "@github/catalyst": "^2.0.0-beta", "@hotwired/turbo": "https://github.com/docusealco/turbo#main", "@hotwired/turbo-rails": "^7.3.0", - "@rails/activestorage": "^7.0.0", "@tabler/icons-vue": "^2.47.0", "autocompleter": "^9.1.0", "autoprefixer": "^10.4.14", diff --git a/yarn.lock b/yarn.lock index ae3295dd..5a90f09c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1125,13 +1125,6 @@ resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-7.0.4.tgz#70a3ca56809f7aaabb80af2f9c01ae51e1a8ed41" integrity sha512-tz4oM+Zn9CYsvtyicsa/AwzKZKL+ITHWkhiu7x+xF77clh2b4Rm+s6xnOgY/sGDWoFWZmtKsE95hxBPkgQQNnQ== -"@rails/activestorage@^7.0.0": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@rails/activestorage/-/activestorage-7.0.5.tgz#0e8fe255a422e5cb9f4e673e02fca845f32a50c1" - integrity sha512-lTOlsVsjz1OYDFRD2SKNH9j2TOA/LTrrIPgRSKyyD3CvJnD1bc65PQt/z6qB1hGqYmtUiklns+SjVWb9xYEqaA== - dependencies: - spark-md5 "^3.0.1" - "@sinclair/typebox@^0.25.16": version "0.25.24" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" @@ -4982,11 +4975,6 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -spark-md5@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.2.tgz#7952c4a30784347abcee73268e473b9c0167e3fc" - integrity sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw== - spdy-transport@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31"