@sanity/migrate
Advanced tools
Comparing version 3.29.1 to 3.29.2-cds-unstable.89
@@ -14,4 +14,4 @@ 'use strict'; | ||
var groq = require('groq-js'); | ||
var client = require('@sanity/client'); | ||
var rxjs = require('rxjs'); | ||
var client$1 = require('@sanity/client'); | ||
var client = require('@sanity/util/client'); | ||
var node_os = require('node:os'); | ||
@@ -369,5 +369,14 @@ var path = require('node:path'); | ||
} | ||
function wrapDocumentsIteratorProducer(factory) { | ||
function documents() { | ||
return factory(); | ||
} | ||
documents[Symbol.asyncIterator] = () => { | ||
throw new Error('The migration is attempting to iterate over the "documents" function, please call the function instead:\n\n // BAD:\n for await (const document of documents) {\n // ...\n }\n\n // GOOD: \u{1F447} This is a function and has to be called\n for await (const document of documents()) {\n // ...\n }\n '); | ||
}; | ||
return documents; | ||
} | ||
function collectMigrationMutations(migration, documents, context) { | ||
const migrate = normalizeMigrateDefinition(migration); | ||
return migrate(documents, context); | ||
return migrate(wrapDocumentsIteratorProducer(documents), context); | ||
} | ||
@@ -1125,132 +1134,6 @@ const MUTATION_ENDPOINT_MAX_BODY_SIZE = 1024 * 256; | ||
} | ||
class ConcurrencyLimiter { | ||
constructor(max) { | ||
this.max = max; | ||
this.current = 0; | ||
this.resolvers = []; | ||
/** | ||
* Indicates when a slot for a new operation is ready. | ||
* If under the limit, it resolves immediately; otherwise, it waits until a slot is free. | ||
*/ | ||
this.ready = () => { | ||
if (this.max === Infinity) return Promise.resolve(); | ||
if (this.current < this.max) { | ||
this.current++; | ||
return Promise.resolve(); | ||
} | ||
return new Promise(resolve => { | ||
this.resolvers.push(resolve); | ||
}); | ||
}; | ||
/** | ||
* Releases a slot, decrementing the current count of operations if nothing is in the queue. | ||
* If there are operations waiting, it allows the next one in the queue to proceed. | ||
*/ | ||
this.release = () => { | ||
if (this.max === Infinity) return; | ||
const nextResolver = this.resolvers.shift(); | ||
if (nextResolver) { | ||
nextResolver(); | ||
return; | ||
} | ||
this.current = Math.max(0, this.current - 1); | ||
}; | ||
} | ||
} | ||
function createClientConcurrencyLimiter(maxConcurrency) { | ||
const limiter = new ConcurrencyLimiter(maxConcurrency); | ||
function wrapClient(client) { | ||
return new Proxy(client, { | ||
get: (target, property) => { | ||
switch (property) { | ||
case "fetch": | ||
{ | ||
return async function () { | ||
await limiter.ready(); | ||
try { | ||
return await target.fetch(...arguments); | ||
} finally { | ||
limiter.release(); | ||
} | ||
}; | ||
} | ||
case "clone": | ||
{ | ||
return function () { | ||
return wrapClient(target.clone(...arguments)); | ||
}; | ||
} | ||
case "config": | ||
{ | ||
return function () { | ||
const result = target.config(...arguments); | ||
if (arguments.length <= 0 ? undefined : arguments[0]) return wrapClient(result); | ||
return result; | ||
}; | ||
} | ||
case "withConfig": | ||
{ | ||
return function () { | ||
return wrapClient(target.withConfig(...arguments)); | ||
}; | ||
} | ||
case "observable": | ||
{ | ||
return wrapObservableClient(target.observable); | ||
} | ||
default: | ||
{ | ||
return target[property]; | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
function wrapObservableClient(observableSanityClient) { | ||
return new Proxy(observableSanityClient, { | ||
get: (target, property) => { | ||
switch (property) { | ||
case "fetch": | ||
{ | ||
return function () { | ||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
return rxjs.from(limiter.ready()).pipe(rxjs.switchMap(() => target.fetch(...args)), rxjs.finalize(() => limiter.release())); | ||
}; | ||
} | ||
case "clone": | ||
{ | ||
return function () { | ||
return wrapObservableClient(target.clone(...arguments)); | ||
}; | ||
} | ||
case "config": | ||
{ | ||
return function () { | ||
const result = target.config(...arguments); | ||
if (arguments.length <= 0 ? undefined : arguments[0]) return wrapObservableClient(result); | ||
return result; | ||
}; | ||
} | ||
case "withConfig": | ||
{ | ||
return function () { | ||
return wrapObservableClient(target.withConfig(...arguments)); | ||
}; | ||
} | ||
default: | ||
{ | ||
return target[property]; | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
return wrapClient; | ||
} | ||
const MAX_FETCH_CONCURRENCY = 10; | ||
const limitClientConcurrency = createClientConcurrencyLimiter(MAX_FETCH_CONCURRENCY); | ||
const limitClientConcurrency = client.createClientConcurrencyLimiter(MAX_FETCH_CONCURRENCY); | ||
function createContextClient(config) { | ||
return restrictClient(limitClientConcurrency(client.createClient({ | ||
return restrictClient(limitClientConcurrency(client$1.createClient({ | ||
...config, | ||
@@ -1257,0 +1140,0 @@ useCdn: false, |
@@ -10,3 +10,3 @@ import { fromString } from '@sanity/util/paths'; | ||
import { createClient } from '@sanity/client'; | ||
import { from, switchMap, finalize } from 'rxjs'; | ||
import { createClientConcurrencyLimiter } from '@sanity/util/client'; | ||
import { tmpdir } from 'node:os'; | ||
@@ -354,5 +354,14 @@ import path from 'node:path'; | ||
} | ||
function wrapDocumentsIteratorProducer(factory) { | ||
function documents() { | ||
return factory(); | ||
} | ||
documents[Symbol.asyncIterator] = () => { | ||
throw new Error('The migration is attempting to iterate over the "documents" function, please call the function instead:\n\n // BAD:\n for await (const document of documents) {\n // ...\n }\n\n // GOOD: \u{1F447} This is a function and has to be called\n for await (const document of documents()) {\n // ...\n }\n '); | ||
}; | ||
return documents; | ||
} | ||
function collectMigrationMutations(migration, documents, context) { | ||
const migrate = normalizeMigrateDefinition(migration); | ||
return migrate(documents, context); | ||
return migrate(wrapDocumentsIteratorProducer(documents), context); | ||
} | ||
@@ -1110,128 +1119,2 @@ const MUTATION_ENDPOINT_MAX_BODY_SIZE = 1024 * 256; | ||
} | ||
class ConcurrencyLimiter { | ||
constructor(max) { | ||
this.max = max; | ||
this.current = 0; | ||
this.resolvers = []; | ||
/** | ||
* Indicates when a slot for a new operation is ready. | ||
* If under the limit, it resolves immediately; otherwise, it waits until a slot is free. | ||
*/ | ||
this.ready = () => { | ||
if (this.max === Infinity) return Promise.resolve(); | ||
if (this.current < this.max) { | ||
this.current++; | ||
return Promise.resolve(); | ||
} | ||
return new Promise(resolve => { | ||
this.resolvers.push(resolve); | ||
}); | ||
}; | ||
/** | ||
* Releases a slot, decrementing the current count of operations if nothing is in the queue. | ||
* If there are operations waiting, it allows the next one in the queue to proceed. | ||
*/ | ||
this.release = () => { | ||
if (this.max === Infinity) return; | ||
const nextResolver = this.resolvers.shift(); | ||
if (nextResolver) { | ||
nextResolver(); | ||
return; | ||
} | ||
this.current = Math.max(0, this.current - 1); | ||
}; | ||
} | ||
} | ||
function createClientConcurrencyLimiter(maxConcurrency) { | ||
const limiter = new ConcurrencyLimiter(maxConcurrency); | ||
function wrapClient(client) { | ||
return new Proxy(client, { | ||
get: (target, property) => { | ||
switch (property) { | ||
case "fetch": | ||
{ | ||
return async function () { | ||
await limiter.ready(); | ||
try { | ||
return await target.fetch(...arguments); | ||
} finally { | ||
limiter.release(); | ||
} | ||
}; | ||
} | ||
case "clone": | ||
{ | ||
return function () { | ||
return wrapClient(target.clone(...arguments)); | ||
}; | ||
} | ||
case "config": | ||
{ | ||
return function () { | ||
const result = target.config(...arguments); | ||
if (arguments.length <= 0 ? undefined : arguments[0]) return wrapClient(result); | ||
return result; | ||
}; | ||
} | ||
case "withConfig": | ||
{ | ||
return function () { | ||
return wrapClient(target.withConfig(...arguments)); | ||
}; | ||
} | ||
case "observable": | ||
{ | ||
return wrapObservableClient(target.observable); | ||
} | ||
default: | ||
{ | ||
return target[property]; | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
function wrapObservableClient(observableSanityClient) { | ||
return new Proxy(observableSanityClient, { | ||
get: (target, property) => { | ||
switch (property) { | ||
case "fetch": | ||
{ | ||
return function () { | ||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
return from(limiter.ready()).pipe(switchMap(() => target.fetch(...args)), finalize(() => limiter.release())); | ||
}; | ||
} | ||
case "clone": | ||
{ | ||
return function () { | ||
return wrapObservableClient(target.clone(...arguments)); | ||
}; | ||
} | ||
case "config": | ||
{ | ||
return function () { | ||
const result = target.config(...arguments); | ||
if (arguments.length <= 0 ? undefined : arguments[0]) return wrapObservableClient(result); | ||
return result; | ||
}; | ||
} | ||
case "withConfig": | ||
{ | ||
return function () { | ||
return wrapObservableClient(target.withConfig(...arguments)); | ||
}; | ||
} | ||
default: | ||
{ | ||
return target[property]; | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
return wrapClient; | ||
} | ||
const MAX_FETCH_CONCURRENCY = 10; | ||
@@ -1238,0 +1121,0 @@ const limitClientConcurrency = createClientConcurrencyLimiter(MAX_FETCH_CONCURRENCY); |
@@ -14,4 +14,4 @@ 'use strict'; | ||
var groq = require('groq-js'); | ||
var client = require('@sanity/client'); | ||
var rxjs = require('rxjs'); | ||
var client$1 = require('@sanity/client'); | ||
var client = require('@sanity/util/client'); | ||
var node_os = require('node:os'); | ||
@@ -369,5 +369,14 @@ var path = require('node:path'); | ||
} | ||
function wrapDocumentsIteratorProducer(factory) { | ||
function documents() { | ||
return factory(); | ||
} | ||
documents[Symbol.asyncIterator] = () => { | ||
throw new Error('The migration is attempting to iterate over the "documents" function, please call the function instead:\n\n // BAD:\n for await (const document of documents) {\n // ...\n }\n\n // GOOD: \u{1F447} This is a function and has to be called\n for await (const document of documents()) {\n // ...\n }\n '); | ||
}; | ||
return documents; | ||
} | ||
function collectMigrationMutations(migration, documents, context) { | ||
const migrate = normalizeMigrateDefinition(migration); | ||
return migrate(documents, context); | ||
return migrate(wrapDocumentsIteratorProducer(documents), context); | ||
} | ||
@@ -1125,132 +1134,6 @@ const MUTATION_ENDPOINT_MAX_BODY_SIZE = 1024 * 256; | ||
} | ||
class ConcurrencyLimiter { | ||
constructor(max) { | ||
this.max = max; | ||
this.current = 0; | ||
this.resolvers = []; | ||
/** | ||
* Indicates when a slot for a new operation is ready. | ||
* If under the limit, it resolves immediately; otherwise, it waits until a slot is free. | ||
*/ | ||
this.ready = () => { | ||
if (this.max === Infinity) return Promise.resolve(); | ||
if (this.current < this.max) { | ||
this.current++; | ||
return Promise.resolve(); | ||
} | ||
return new Promise(resolve => { | ||
this.resolvers.push(resolve); | ||
}); | ||
}; | ||
/** | ||
* Releases a slot, decrementing the current count of operations if nothing is in the queue. | ||
* If there are operations waiting, it allows the next one in the queue to proceed. | ||
*/ | ||
this.release = () => { | ||
if (this.max === Infinity) return; | ||
const nextResolver = this.resolvers.shift(); | ||
if (nextResolver) { | ||
nextResolver(); | ||
return; | ||
} | ||
this.current = Math.max(0, this.current - 1); | ||
}; | ||
} | ||
} | ||
function createClientConcurrencyLimiter(maxConcurrency) { | ||
const limiter = new ConcurrencyLimiter(maxConcurrency); | ||
function wrapClient(client) { | ||
return new Proxy(client, { | ||
get: (target, property) => { | ||
switch (property) { | ||
case "fetch": | ||
{ | ||
return async function () { | ||
await limiter.ready(); | ||
try { | ||
return await target.fetch(...arguments); | ||
} finally { | ||
limiter.release(); | ||
} | ||
}; | ||
} | ||
case "clone": | ||
{ | ||
return function () { | ||
return wrapClient(target.clone(...arguments)); | ||
}; | ||
} | ||
case "config": | ||
{ | ||
return function () { | ||
const result = target.config(...arguments); | ||
if (arguments.length <= 0 ? undefined : arguments[0]) return wrapClient(result); | ||
return result; | ||
}; | ||
} | ||
case "withConfig": | ||
{ | ||
return function () { | ||
return wrapClient(target.withConfig(...arguments)); | ||
}; | ||
} | ||
case "observable": | ||
{ | ||
return wrapObservableClient(target.observable); | ||
} | ||
default: | ||
{ | ||
return target[property]; | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
function wrapObservableClient(observableSanityClient) { | ||
return new Proxy(observableSanityClient, { | ||
get: (target, property) => { | ||
switch (property) { | ||
case "fetch": | ||
{ | ||
return function () { | ||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
return rxjs.from(limiter.ready()).pipe(rxjs.switchMap(() => target.fetch(...args)), rxjs.finalize(() => limiter.release())); | ||
}; | ||
} | ||
case "clone": | ||
{ | ||
return function () { | ||
return wrapObservableClient(target.clone(...arguments)); | ||
}; | ||
} | ||
case "config": | ||
{ | ||
return function () { | ||
const result = target.config(...arguments); | ||
if (arguments.length <= 0 ? undefined : arguments[0]) return wrapObservableClient(result); | ||
return result; | ||
}; | ||
} | ||
case "withConfig": | ||
{ | ||
return function () { | ||
return wrapObservableClient(target.withConfig(...arguments)); | ||
}; | ||
} | ||
default: | ||
{ | ||
return target[property]; | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
return wrapClient; | ||
} | ||
const MAX_FETCH_CONCURRENCY = 10; | ||
const limitClientConcurrency = createClientConcurrencyLimiter(MAX_FETCH_CONCURRENCY); | ||
const limitClientConcurrency = client.createClientConcurrencyLimiter(MAX_FETCH_CONCURRENCY); | ||
function createContextClient(config) { | ||
return restrictClient(limitClientConcurrency(client.createClient({ | ||
return restrictClient(limitClientConcurrency(client$1.createClient({ | ||
...config, | ||
@@ -1257,0 +1140,0 @@ useCdn: false, |
{ | ||
"name": "@sanity/migrate", | ||
"version": "3.29.1", | ||
"version": "3.29.2-cds-unstable.89+54f9f51031", | ||
"description": "Tooling for running data migrations on Sanity.io projects", | ||
@@ -67,5 +67,5 @@ "keywords": [ | ||
"@bjoerge/mutiny": "^0.5.1", | ||
"@sanity/client": "^6.12.4", | ||
"@sanity/types": "3.29.1", | ||
"@sanity/util": "3.29.1", | ||
"@sanity/client": "^6.13.3", | ||
"@sanity/types": "3.29.2-cds-unstable.89+54f9f51031", | ||
"@sanity/util": "3.29.2-cds-unstable.89+54f9f51031", | ||
"arrify": "^2.0.1", | ||
@@ -75,7 +75,8 @@ "debug": "^4.3.4", | ||
"groq-js": "^1.4.1", | ||
"p-map": "^7.0.1", | ||
"rxjs": "^7.8.0" | ||
"p-map": "^7.0.1" | ||
}, | ||
"devDependencies": { | ||
"@jest/globals": "^29.7.0", | ||
"@types/arrify": "^2.0.1", | ||
"@types/debug": "^4.1.12", | ||
"rimraf": "^3.0.2" | ||
@@ -86,3 +87,3 @@ }, | ||
}, | ||
"gitHead": "8b27a1c327519bfd5f6101e3dd41d11f48dfca2e" | ||
"gitHead": "54f9f510310dac6733e0de38dcf15d24b796d8fd" | ||
} |
@@ -5,2 +5,4 @@ /* eslint-disable no-constant-condition */ | ||
import {describe, expect, test} from '@jest/globals' | ||
import {decodeText, parse} from '../../it-utils' | ||
@@ -7,0 +9,0 @@ import {firstValueFrom} from '../../it-utils/firstValueFrom' |
@@ -24,3 +24,3 @@ import {type FileHandle, open, unlink} from 'node:fs/promises' | ||
export function bufferThroughFile( | ||
source: ReadableStream<Uint8Array | string>, | ||
source: ReadableStream<Uint8Array>, | ||
filename: string, | ||
@@ -49,3 +49,3 @@ options?: {signal: AbortSignal; keepFile?: boolean}, | ||
async function pump(reader: ReadableStreamDefaultReader<Uint8Array | string>) { | ||
async function pump(reader: ReadableStreamDefaultReader<Uint8Array>) { | ||
try { | ||
@@ -52,0 +52,0 @@ // eslint-disable-next-line no-constant-condition |
@@ -0,1 +1,3 @@ | ||
import {expect, test} from '@jest/globals' | ||
import {parseJSON} from '../json' | ||
@@ -2,0 +4,0 @@ |
@@ -0,1 +1,3 @@ | ||
import {expect, test} from '@jest/globals' | ||
import {split} from '../split' | ||
@@ -2,0 +4,0 @@ |
@@ -6,2 +6,28 @@ import {type SanityDocument} from '@sanity/types' | ||
async function* empty() {} | ||
function wrapDocumentsIteratorProducer(factory: () => AsyncIterableIterator<SanityDocument>) { | ||
function documents() { | ||
return factory() | ||
} | ||
;(documents as any)[Symbol.asyncIterator] = () => { | ||
throw new Error( | ||
`The migration is attempting to iterate over the "documents" function, please call the function instead: | ||
// BAD: | ||
for await (const document of documents) { | ||
// ... | ||
} | ||
// GOOD: 👇 This is a function and has to be called | ||
for await (const document of documents()) { | ||
// ... | ||
} | ||
`, | ||
) | ||
} | ||
return documents | ||
} | ||
export function collectMigrationMutations( | ||
@@ -13,3 +39,3 @@ migration: Migration, | ||
const migrate = normalizeMigrateDefinition(migration) | ||
return migrate(documents, context) | ||
return migrate(wrapDocumentsIteratorProducer(documents), context) | ||
} |
// this is the number of requests allowed inflight at once. this is done to prevent | ||
// the validation library from overwhelming our backend | ||
import {createClientConcurrencyLimiter} from './client-concurrency-limiter/createClientConcurrencyLimiter' | ||
import {createClientConcurrencyLimiter} from '@sanity/util/client' | ||
@@ -5,0 +5,0 @@ const MAX_FETCH_CONCURRENCY = 10 |
@@ -0,1 +1,3 @@ | ||
import {expect, test} from '@jest/globals' | ||
import {decodeText, parse, toArray} from '../../it-utils' | ||
@@ -2,0 +4,0 @@ import {fromExportArchive} from '../fromExportArchive' |
@@ -0,1 +1,3 @@ | ||
import {expect, test} from '@jest/globals' | ||
import {readFileAsWebStream} from '../../fs-webstream/readFileAsWebStream' | ||
@@ -2,0 +4,0 @@ import {streamToAsyncIterator} from '../../utils/streamToAsyncIterator' |
@@ -0,1 +1,3 @@ | ||
import {expect, test} from '@jest/globals' | ||
import {readFileAsWebStream} from '../../fs-webstream/readFileAsWebStream' | ||
@@ -2,0 +4,0 @@ import {toArray} from '../../it-utils/toArray' |
@@ -0,1 +1,3 @@ | ||
import {expect, test} from '@jest/globals' | ||
import {readFileAsWebStream} from '../../fs-webstream/readFileAsWebStream' | ||
@@ -2,0 +4,0 @@ import {decodeText} from '../../it-utils/decodeText' |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6604429
9
368
11848
4
1
5
- Removedrxjs@^7.8.0
- Removed@sanity/types@3.29.1(transitive)
- Removed@sanity/util@3.29.1(transitive)
- Removed@types/prop-types@15.7.13(transitive)
- Removed@types/react@18.3.10(transitive)
- Removedcsstype@3.1.3(transitive)
- Removeddom-walk@0.1.2(transitive)
- Removedget-random-values@1.2.2(transitive)
- Removedget-random-values-esm@1.0.0(transitive)
- Removedglobal@4.4.0(transitive)
- Removedmin-document@2.19.0(transitive)
- Removedmoment@2.30.1(transitive)
- Removedprocess@0.11.10(transitive)
Updated@sanity/client@^6.13.3