mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
fix: randomstring dep does not work in browser with rolldown-vite (#9624)
* fix: randomstring dep does not work in browser with rolldown-vite * fix: Last usage of randomstring, docs * feedback
This commit is contained in:
@@ -203,7 +203,6 @@
|
|||||||
"prosemirror-transform": "1.10.0",
|
"prosemirror-transform": "1.10.0",
|
||||||
"prosemirror-view": "^1.39.1",
|
"prosemirror-view": "^1.39.1",
|
||||||
"query-string": "^7.1.3",
|
"query-string": "^7.1.3",
|
||||||
"randomstring": "1.3.1",
|
|
||||||
"rate-limiter-flexible": "^2.4.2",
|
"rate-limiter-flexible": "^2.4.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-avatar-editor": "^13.0.2",
|
"react-avatar-editor": "^13.0.2",
|
||||||
@@ -314,7 +313,6 @@
|
|||||||
"@types/pluralize": "^0.0.33",
|
"@types/pluralize": "^0.0.33",
|
||||||
"@types/png-chunks-extract": "^1.0.2",
|
"@types/png-chunks-extract": "^1.0.2",
|
||||||
"@types/quoted-printable": "^1.0.2",
|
"@types/quoted-printable": "^1.0.2",
|
||||||
"@types/randomstring": "^1.3.0",
|
|
||||||
"@types/react": "^17.0.34",
|
"@types/react": "^17.0.34",
|
||||||
"@types/react-avatar-editor": "^13.0.4",
|
"@types/react-avatar-editor": "^13.0.4",
|
||||||
"@types/react-color": "^3.0.13",
|
"@types/react-color": "^3.0.13",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import randomstring from "randomstring";
|
import { randomString } from "@shared/random";
|
||||||
import { IntegrationService } from "@shared/types";
|
import { IntegrationService } from "@shared/types";
|
||||||
import { IntegrationAuthentication, SearchQuery } from "@server/models";
|
import { IntegrationAuthentication, SearchQuery } from "@server/models";
|
||||||
import { buildDocument, buildTeam, buildUser } from "@server/test/factories";
|
import { buildDocument, buildTeam, buildUser } from "@server/test/factories";
|
||||||
@@ -24,19 +24,19 @@ describe("#hooks.unfurl", () => {
|
|||||||
service: IntegrationService.Slack,
|
service: IntegrationService.Slack,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: user.teamId,
|
teamId: user.teamId,
|
||||||
token: randomstring.generate(32),
|
token: randomString(32),
|
||||||
});
|
});
|
||||||
|
|
||||||
const res = await server.post("/api/hooks.unfurl", {
|
const res = await server.post("/api/hooks.unfurl", {
|
||||||
body: {
|
body: {
|
||||||
token: env.SLACK_VERIFICATION_TOKEN,
|
token: env.SLACK_VERIFICATION_TOKEN,
|
||||||
team_id: `T${randomstring.generate(8)}`,
|
team_id: `T${randomString(8)}`,
|
||||||
api_app_id: `A${randomstring.generate(8)}`,
|
api_app_id: `A${randomString(8)}`,
|
||||||
event: {
|
event: {
|
||||||
type: "link_shared",
|
type: "link_shared",
|
||||||
channel: `C${randomstring.generate(8)}`,
|
channel: `C${randomString(8)}`,
|
||||||
user: user.authentications[0].providerId,
|
user: user.authentications[0].providerId,
|
||||||
message_ts: randomstring.generate(12),
|
message_ts: randomString(12),
|
||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
domain: "getoutline.com",
|
domain: "getoutline.com",
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import filter from "lodash/filter";
|
import filter from "lodash/filter";
|
||||||
import includes from "lodash/includes";
|
import includes from "lodash/includes";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import randomstring from "randomstring";
|
|
||||||
import * as React from "react";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useTranslation, Trans } from "react-i18next";
|
import { useTranslation, Trans } from "react-i18next";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
import { randomString } from "@shared/random";
|
||||||
import { TeamPreference } from "@shared/types";
|
import { TeamPreference } from "@shared/types";
|
||||||
import WebhookSubscription from "~/models/WebhookSubscription";
|
import WebhookSubscription from "~/models/WebhookSubscription";
|
||||||
import Button from "~/components/Button";
|
import Button from "~/components/Button";
|
||||||
@@ -159,7 +158,7 @@ interface FormData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generateSigningSecret() {
|
function generateSigningSecret() {
|
||||||
return `ol_whs_${randomstring.generate(32)}`;
|
return `ol_whs_${randomString(32)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function WebhookSubscriptionForm({ handleSubmit, webhookSubscription }: Props) {
|
function WebhookSubscriptionForm({ handleSubmit, webhookSubscription }: Props) {
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import addressparser, { EmailAddress } from "addressparser";
|
|||||||
import Bull from "bull";
|
import Bull from "bull";
|
||||||
import invariant from "invariant";
|
import invariant from "invariant";
|
||||||
import { Node } from "prosemirror-model";
|
import { Node } from "prosemirror-model";
|
||||||
import randomstring from "randomstring";
|
import { randomString } from "@shared/random";
|
||||||
import * as React from "react";
|
|
||||||
import { TeamPreference } from "@shared/types";
|
import { TeamPreference } from "@shared/types";
|
||||||
import { Day } from "@shared/utils/time";
|
import { Day } from "@shared/utils/time";
|
||||||
import mailer from "@server/emails/mailer";
|
import mailer from "@server/emails/mailer";
|
||||||
@@ -200,7 +199,7 @@ export default abstract class BaseEmail<
|
|||||||
address:
|
address:
|
||||||
env.isCloudHosted &&
|
env.isCloudHosted &&
|
||||||
this.category === EmailMessageCategory.Authentication
|
this.category === EmailMessageCategory.Authentication
|
||||||
? `noreply-${randomstring.generate(24)}@${domain}`
|
? `noreply-${randomString(24)}@${domain}`
|
||||||
: parsedFrom.address,
|
: parsedFrom.address,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { DefaultState } from "koa";
|
import { DefaultState } from "koa";
|
||||||
import randomstring from "randomstring";
|
import { randomString } from "@shared/random";
|
||||||
import { Scope } from "@shared/types";
|
import { Scope } from "@shared/types";
|
||||||
import {
|
import {
|
||||||
buildUser,
|
buildUser,
|
||||||
@@ -106,7 +106,7 @@ describe("Authentication middleware", () => {
|
|||||||
{
|
{
|
||||||
// @ts-expect-error mock request
|
// @ts-expect-error mock request
|
||||||
request: {
|
request: {
|
||||||
get: jest.fn(() => `Bearer ${randomstring.generate(38)}`),
|
get: jest.fn(() => `Bearer ${randomString(38)}`),
|
||||||
},
|
},
|
||||||
state,
|
state,
|
||||||
cache: {},
|
cache: {},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import randomstring from "randomstring";
|
import { randomString } from "@shared/random";
|
||||||
import { buildApiKey } from "@server/test/factories";
|
import { buildApiKey } from "@server/test/factories";
|
||||||
import ApiKey from "./ApiKey";
|
import ApiKey from "./ApiKey";
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ describe("#ApiKey", () => {
|
|||||||
it("should match an API secret", async () => {
|
it("should match an API secret", async () => {
|
||||||
const apiKey = await buildApiKey();
|
const apiKey = await buildApiKey();
|
||||||
expect(ApiKey.match(apiKey.value!)).toBe(true);
|
expect(ApiKey.match(apiKey.value!)).toBe(true);
|
||||||
expect(ApiKey.match(`${randomstring.generate(38)}`)).toBe(true);
|
expect(ApiKey.match(`${randomString(38)}`)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not match non secrets", async () => {
|
it("should not match non secrets", async () => {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Matches } from "class-validator";
|
import { Matches } from "class-validator";
|
||||||
import { subMinutes } from "date-fns";
|
import { subMinutes } from "date-fns";
|
||||||
import randomstring from "randomstring";
|
|
||||||
import { InferAttributes, InferCreationAttributes, Op } from "sequelize";
|
import { InferAttributes, InferCreationAttributes, Op } from "sequelize";
|
||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
@@ -14,6 +13,7 @@ import {
|
|||||||
AfterFind,
|
AfterFind,
|
||||||
BeforeSave,
|
BeforeSave,
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript";
|
||||||
|
import { randomString } from "@shared/random";
|
||||||
import { ApiKeyValidation } from "@shared/validations";
|
import { ApiKeyValidation } from "@shared/validations";
|
||||||
import { hash } from "@server/utils/crypto";
|
import { hash } from "@server/utils/crypto";
|
||||||
import User from "./User";
|
import User from "./User";
|
||||||
@@ -95,7 +95,7 @@ class ApiKey extends ParanoidModel<
|
|||||||
@BeforeValidate
|
@BeforeValidate
|
||||||
public static async generateSecret(model: ApiKey) {
|
public static async generateSecret(model: ApiKey) {
|
||||||
if (!model.hash) {
|
if (!model.hash) {
|
||||||
const secret = `${ApiKey.prefix}${randomstring.generate(38)}`;
|
const secret = `${ApiKey.prefix}${randomString(38)}`;
|
||||||
model.value = model.secret || secret;
|
model.value = model.secret || secret;
|
||||||
model.hash = hash(model.value);
|
model.hash = hash(model.value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import randomstring from "randomstring";
|
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { randomString } from "@shared/random";
|
||||||
import slugify from "@shared/utils/slugify";
|
import slugify from "@shared/utils/slugify";
|
||||||
import {
|
import {
|
||||||
buildUser,
|
buildUser,
|
||||||
@@ -511,7 +511,7 @@ describe("#findByPk", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return null when no collection is found with urlId", async () => {
|
it("should return null when no collection is found with urlId", async () => {
|
||||||
const id = `${slugify("test collection")}-${randomstring.generate(15)}`;
|
const id = `${slugify("test collection")}-${randomString(15)}`;
|
||||||
const response = await Collection.findByPk(id);
|
const response = await Collection.findByPk(id);
|
||||||
expect(response).toBe(null);
|
expect(response).toBe(null);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
ArrayUnique,
|
ArrayUnique,
|
||||||
IsUrl,
|
IsUrl,
|
||||||
} from "class-validator";
|
} from "class-validator";
|
||||||
import rs from "randomstring";
|
|
||||||
import { InferAttributes, InferCreationAttributes } from "sequelize";
|
import { InferAttributes, InferCreationAttributes } from "sequelize";
|
||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
@@ -17,6 +16,7 @@ import {
|
|||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
AllowNull,
|
AllowNull,
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript";
|
||||||
|
import { randomString } from "@shared/random";
|
||||||
import { OAuthClientValidation } from "@shared/validations";
|
import { OAuthClientValidation } from "@shared/validations";
|
||||||
import Team from "@server/models/Team";
|
import Team from "@server/models/Team";
|
||||||
import User from "@server/models/User";
|
import User from "@server/models/User";
|
||||||
@@ -144,7 +144,7 @@ class OAuthClient extends ParanoidModel<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static generateNewClientId(): string {
|
private static generateNewClientId(): string {
|
||||||
return rs.generate({
|
return randomString({
|
||||||
length: 20,
|
length: 20,
|
||||||
charset: "alphanumeric",
|
charset: "alphanumeric",
|
||||||
capitalization: "lowercase",
|
capitalization: "lowercase",
|
||||||
@@ -152,7 +152,7 @@ class OAuthClient extends ParanoidModel<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static generateNewClientSecret(): string {
|
private static generateNewClientSecret(): string {
|
||||||
return `${OAuthClient.clientSecretPrefix}${rs.generate(32)}`;
|
return `${OAuthClient.clientSecretPrefix}${randomString(32)}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Context, Next } from "koa";
|
import { Context, Next } from "koa";
|
||||||
import Router from "koa-router";
|
import Router from "koa-router";
|
||||||
import randomstring from "randomstring";
|
import { randomString } from "@shared/random";
|
||||||
import userInviter, { Invite } from "@server/commands/userInviter";
|
import userInviter, { Invite } from "@server/commands/userInviter";
|
||||||
import env from "@server/env";
|
import env from "@server/env";
|
||||||
import Logger from "@server/logging/Logger";
|
import Logger from "@server/logging/Logger";
|
||||||
@@ -33,7 +33,7 @@ router.post(
|
|||||||
const invites = Array(Math.min(count, 100))
|
const invites = Array(Math.min(count, 100))
|
||||||
.fill(0)
|
.fill(0)
|
||||||
.map(() => {
|
.map(() => {
|
||||||
const rando = randomstring.generate(10);
|
const rando = randomString(10);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
email: `${rando}@example.com`,
|
email: `${rando}@example.com`,
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { faker } from "@faker-js/faker";
|
|||||||
import isNil from "lodash/isNil";
|
import isNil from "lodash/isNil";
|
||||||
import isNull from "lodash/isNull";
|
import isNull from "lodash/isNull";
|
||||||
import { Node } from "prosemirror-model";
|
import { Node } from "prosemirror-model";
|
||||||
import randomstring from "randomstring";
|
|
||||||
import { InferCreationAttributes } from "sequelize";
|
import { InferCreationAttributes } from "sequelize";
|
||||||
import { DeepPartial } from "utility-types";
|
import { DeepPartial } from "utility-types";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { randomString } from "@shared/random";
|
||||||
import {
|
import {
|
||||||
CollectionPermission,
|
CollectionPermission,
|
||||||
FileOperationState,
|
FileOperationState,
|
||||||
@@ -154,7 +154,7 @@ export function buildTeam(
|
|||||||
authenticationProviders: [
|
authenticationProviders: [
|
||||||
{
|
{
|
||||||
name: "slack",
|
name: "slack",
|
||||||
providerId: randomstring.generate(32),
|
providerId: randomString(32),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
...overrides,
|
...overrides,
|
||||||
@@ -215,7 +215,7 @@ export async function buildUser(overrides: Partial<User> = {}) {
|
|||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
authenticationProviderId: authenticationProvider.id,
|
authenticationProviderId: authenticationProvider.id,
|
||||||
providerId: randomstring.generate(32),
|
providerId: randomString(32),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
@@ -272,7 +272,7 @@ export async function buildIntegration(overrides: Partial<Integration> = {}) {
|
|||||||
service: IntegrationService.Slack,
|
service: IntegrationService.Slack,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: user.teamId,
|
teamId: user.teamId,
|
||||||
token: randomstring.generate(32),
|
token: randomString(32),
|
||||||
scopes: ["example", "scopes", "here"],
|
scopes: ["example", "scopes", "here"],
|
||||||
});
|
});
|
||||||
return Integration.create({
|
return Integration.create({
|
||||||
@@ -737,7 +737,7 @@ export async function buildOAuthAuthorizationCode(
|
|||||||
overrides.expiresAt = new Date();
|
overrides.expiresAt = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = randomstring.generate(32);
|
const code = randomString(32);
|
||||||
|
|
||||||
let client;
|
let client;
|
||||||
if (overrides.oauthClientId) {
|
if (overrides.oauthClientId) {
|
||||||
@@ -817,11 +817,11 @@ export function buildCommentMark(overrides: {
|
|||||||
resolved?: boolean;
|
resolved?: boolean;
|
||||||
}) {
|
}) {
|
||||||
if (!overrides.id) {
|
if (!overrides.id) {
|
||||||
overrides.id = randomstring.generate(10);
|
overrides.id = randomString(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overrides.userId) {
|
if (!overrides.userId) {
|
||||||
overrides.userId = randomstring.generate(10);
|
overrides.userId = randomString(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
import randomstring from "randomstring";
|
import { randomString } from "@shared/random";
|
||||||
|
|
||||||
const UrlIdLength = 10;
|
const UrlIdLength = 10;
|
||||||
|
|
||||||
export const generateUrlId = () => randomstring.generate(UrlIdLength);
|
export const generateUrlId = () => randomString(UrlIdLength);
|
||||||
|
|||||||
@@ -0,0 +1,186 @@
|
|||||||
|
import { randomString } from "./random";
|
||||||
|
|
||||||
|
describe("randomString", () => {
|
||||||
|
describe("with number parameter", () => {
|
||||||
|
it("should generate string of correct length", () => {
|
||||||
|
const result = randomString(10);
|
||||||
|
expect(result).toHaveLength(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate alphanumeric mixed case by default", () => {
|
||||||
|
const result = randomString(100);
|
||||||
|
expect(result).toMatch(/^[a-zA-Z0-9]+$/);
|
||||||
|
// Check that it contains both cases and numbers (with high probability)
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
expect(result).toMatch(/[0-9]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate different strings on multiple calls", () => {
|
||||||
|
const result1 = randomString(20);
|
||||||
|
const result2 = randomString(20);
|
||||||
|
expect(result1).not.toEqual(result2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("with object parameter", () => {
|
||||||
|
describe("charset: numeric", () => {
|
||||||
|
it("should generate only numbers", () => {
|
||||||
|
const result = randomString({ length: 50, charset: "numeric" });
|
||||||
|
expect(result).toMatch(/^[0-9]+$/);
|
||||||
|
expect(result).toHaveLength(50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should ignore capitalization for numeric charset", () => {
|
||||||
|
const lowercase = randomString({
|
||||||
|
length: 50,
|
||||||
|
charset: "numeric",
|
||||||
|
capitalization: "lowercase",
|
||||||
|
});
|
||||||
|
const uppercase = randomString({
|
||||||
|
length: 50,
|
||||||
|
charset: "numeric",
|
||||||
|
capitalization: "uppercase",
|
||||||
|
});
|
||||||
|
const mixed = randomString({
|
||||||
|
length: 50,
|
||||||
|
charset: "numeric",
|
||||||
|
capitalization: "mixed",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(lowercase).toMatch(/^[0-9]+$/);
|
||||||
|
expect(uppercase).toMatch(/^[0-9]+$/);
|
||||||
|
expect(mixed).toMatch(/^[0-9]+$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("charset: alphabetic", () => {
|
||||||
|
it("should generate only letters with mixed capitalization by default", () => {
|
||||||
|
const result = randomString({ length: 100, charset: "alphabetic" });
|
||||||
|
expect(result).toMatch(/^[a-zA-Z]+$/);
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate only lowercase letters", () => {
|
||||||
|
const result = randomString({
|
||||||
|
length: 50,
|
||||||
|
charset: "alphabetic",
|
||||||
|
capitalization: "lowercase",
|
||||||
|
});
|
||||||
|
expect(result).toMatch(/^[a-z]+$/);
|
||||||
|
expect(result).toHaveLength(50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate only uppercase letters", () => {
|
||||||
|
const result = randomString({
|
||||||
|
length: 50,
|
||||||
|
charset: "alphabetic",
|
||||||
|
capitalization: "uppercase",
|
||||||
|
});
|
||||||
|
expect(result).toMatch(/^[A-Z]+$/);
|
||||||
|
expect(result).toHaveLength(50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate mixed case letters", () => {
|
||||||
|
const result = randomString({
|
||||||
|
length: 100,
|
||||||
|
charset: "alphabetic",
|
||||||
|
capitalization: "mixed",
|
||||||
|
});
|
||||||
|
expect(result).toMatch(/^[a-zA-Z]+$/);
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("charset: alphanumeric", () => {
|
||||||
|
it("should generate letters and numbers with mixed capitalization by default", () => {
|
||||||
|
const result = randomString({ length: 100, charset: "alphanumeric" });
|
||||||
|
expect(result).toMatch(/^[a-zA-Z0-9]+$/);
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
expect(result).toMatch(/[0-9]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate lowercase letters and numbers", () => {
|
||||||
|
const result = randomString({
|
||||||
|
length: 100,
|
||||||
|
charset: "alphanumeric",
|
||||||
|
capitalization: "lowercase",
|
||||||
|
});
|
||||||
|
expect(result).toMatch(/^[a-z0-9]+$/);
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[0-9]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate uppercase letters and numbers", () => {
|
||||||
|
const result = randomString({
|
||||||
|
length: 100,
|
||||||
|
charset: "alphanumeric",
|
||||||
|
capitalization: "uppercase",
|
||||||
|
});
|
||||||
|
expect(result).toMatch(/^[A-Z0-9]+$/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
expect(result).toMatch(/[0-9]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate mixed case letters and numbers", () => {
|
||||||
|
const result = randomString({
|
||||||
|
length: 100,
|
||||||
|
charset: "alphanumeric",
|
||||||
|
capitalization: "mixed",
|
||||||
|
});
|
||||||
|
expect(result).toMatch(/^[a-zA-Z0-9]+$/);
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
expect(result).toMatch(/[0-9]/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("default values", () => {
|
||||||
|
it("should default to alphanumeric charset", () => {
|
||||||
|
const result = randomString({ length: 100 });
|
||||||
|
expect(result).toMatch(/^[a-zA-Z0-9]+$/);
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
expect(result).toMatch(/[0-9]/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should default to mixed capitalization", () => {
|
||||||
|
const result = randomString({ length: 100, charset: "alphabetic" });
|
||||||
|
expect(result).toMatch(/^[a-zA-Z]+$/);
|
||||||
|
expect(result).toMatch(/[a-z]/);
|
||||||
|
expect(result).toMatch(/[A-Z]/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("edge cases", () => {
|
||||||
|
it("should handle length of 1", () => {
|
||||||
|
const result = randomString({ length: 1, charset: "alphabetic" });
|
||||||
|
expect(result).toHaveLength(1);
|
||||||
|
expect(result).toMatch(/^[a-zA-Z]$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle length of 0", () => {
|
||||||
|
const result = randomString({ length: 0 });
|
||||||
|
expect(result).toHaveLength(0);
|
||||||
|
expect(result).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should generate different strings on multiple calls", () => {
|
||||||
|
const result1 = randomString({
|
||||||
|
length: 20,
|
||||||
|
charset: "alphanumeric",
|
||||||
|
capitalization: "lowercase",
|
||||||
|
});
|
||||||
|
const result2 = randomString({
|
||||||
|
length: 20,
|
||||||
|
charset: "alphanumeric",
|
||||||
|
capitalization: "lowercase",
|
||||||
|
});
|
||||||
|
expect(result1).not.toEqual(result2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
+63
-3
@@ -1,6 +1,66 @@
|
|||||||
const randomInteger = (min: number, max: number) =>
|
/**
|
||||||
|
* Generate a random integer within a given range.
|
||||||
|
*
|
||||||
|
* @param min - The minimum value of the range.
|
||||||
|
* @param max - The maximum value of the range.
|
||||||
|
* @returns A random integer within the range.
|
||||||
|
*/
|
||||||
|
export const randomInteger = (min: number, max: number) =>
|
||||||
Math.floor(Math.random() * (max - min + 1) + min);
|
Math.floor(Math.random() * (max - min + 1) + min);
|
||||||
|
|
||||||
const randomElement = <T>(arr: T[]): T => arr[randomInteger(0, arr.length - 1)];
|
/**
|
||||||
|
* Choose a random element from an array.
|
||||||
|
*
|
||||||
|
* @param arr - The array to choose from.
|
||||||
|
* @returns A random element from the array.
|
||||||
|
*/
|
||||||
|
export const randomElement = <T>(arr: T[]): T =>
|
||||||
|
arr[randomInteger(0, arr.length - 1)];
|
||||||
|
|
||||||
export { randomInteger, randomElement };
|
type RandomStringOptions = {
|
||||||
|
/** The length of the output string. */
|
||||||
|
length: number;
|
||||||
|
/** The character set to use. */
|
||||||
|
charset?: "alphabetic" | "numeric" | "alphanumeric";
|
||||||
|
/** The capitalization of the string. */
|
||||||
|
capitalization?: "lowercase" | "uppercase" | "mixed";
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a random string of a given length and charset.
|
||||||
|
*
|
||||||
|
* @param options - The length of the string or an object with options.
|
||||||
|
* @returns A random string.
|
||||||
|
*/
|
||||||
|
export const randomString = (options: number | RandomStringOptions) => {
|
||||||
|
const lowercase = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
const uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
const numeric = "0123456789";
|
||||||
|
|
||||||
|
const length = typeof options === "number" ? options : options.length;
|
||||||
|
const charset =
|
||||||
|
typeof options === "number"
|
||||||
|
? "alphanumeric"
|
||||||
|
: options.charset || "alphanumeric";
|
||||||
|
const capitalization =
|
||||||
|
typeof options === "number" ? "mixed" : options.capitalization || "mixed";
|
||||||
|
|
||||||
|
const chars =
|
||||||
|
charset === "numeric"
|
||||||
|
? numeric
|
||||||
|
: charset === "alphabetic"
|
||||||
|
? capitalization === "lowercase"
|
||||||
|
? lowercase
|
||||||
|
: capitalization === "uppercase"
|
||||||
|
? uppercase
|
||||||
|
: lowercase + uppercase
|
||||||
|
: capitalization === "lowercase"
|
||||||
|
? lowercase + numeric
|
||||||
|
: capitalization === "uppercase"
|
||||||
|
? uppercase + numeric
|
||||||
|
: lowercase + uppercase + numeric;
|
||||||
|
|
||||||
|
const array = new Uint8Array(length);
|
||||||
|
crypto.getRandomValues(array);
|
||||||
|
return Array.from(array, (x) => chars[x % chars.length]).join("");
|
||||||
|
};
|
||||||
|
|||||||
@@ -744,14 +744,7 @@
|
|||||||
"@jridgewell/trace-mapping" "^0.3.28"
|
"@jridgewell/trace-mapping" "^0.3.28"
|
||||||
jsesc "^3.0.2"
|
jsesc "^3.0.2"
|
||||||
|
|
||||||
"@babel/helper-annotate-as-pure@^7.22.5", "@babel/helper-annotate-as-pure@^7.27.1":
|
"@babel/helper-annotate-as-pure@^7.22.5", "@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3":
|
||||||
version "7.27.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.1.tgz#4345d81a9a46a6486e24d069469f13e60445c05d"
|
|
||||||
integrity sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==
|
|
||||||
dependencies:
|
|
||||||
"@babel/types" "^7.27.1"
|
|
||||||
|
|
||||||
"@babel/helper-annotate-as-pure@^7.27.3":
|
|
||||||
version "7.27.3"
|
version "7.27.3"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5"
|
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5"
|
||||||
integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==
|
integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==
|
||||||
@@ -1693,15 +1686,7 @@
|
|||||||
"@babel/types" "^7.28.0"
|
"@babel/types" "^7.28.0"
|
||||||
debug "^4.3.1"
|
debug "^4.3.1"
|
||||||
|
|
||||||
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.6", "@babel/types@^7.28.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
|
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.27.6", "@babel/types@^7.28.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
|
||||||
version "7.28.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.0.tgz#2fd0159a6dc7353933920c43136335a9b264d950"
|
|
||||||
integrity sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==
|
|
||||||
dependencies:
|
|
||||||
"@babel/helper-string-parser" "^7.27.1"
|
|
||||||
"@babel/helper-validator-identifier" "^7.27.1"
|
|
||||||
|
|
||||||
"@babel/types@^7.27.3":
|
|
||||||
version "7.28.1"
|
version "7.28.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.1.tgz#2aaf3c10b31ba03a77ac84f52b3912a0edef4cf9"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.1.tgz#2aaf3c10b31ba03a77ac84f52b3912a0edef4cf9"
|
||||||
integrity sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==
|
integrity sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==
|
||||||
@@ -5151,11 +5136,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/quoted-printable/-/quoted-printable-1.0.2.tgz#1d89663da9ded3df30d162558c5d18759831f659"
|
resolved "https://registry.yarnpkg.com/@types/quoted-printable/-/quoted-printable-1.0.2.tgz#1d89663da9ded3df30d162558c5d18759831f659"
|
||||||
integrity "sha1-HYlmPane098w0WJVjF0YdZgx9lk= sha512-3B28oB1rRaZNb3N5dlxysm8lH1ujzvReDuYBiIO4jvpTIg9ksrILCNgPxSGVyTWE/qwuxzgHaVehwMK3CVqAtA=="
|
integrity "sha1-HYlmPane098w0WJVjF0YdZgx9lk= sha512-3B28oB1rRaZNb3N5dlxysm8lH1ujzvReDuYBiIO4jvpTIg9ksrILCNgPxSGVyTWE/qwuxzgHaVehwMK3CVqAtA=="
|
||||||
|
|
||||||
"@types/randomstring@^1.3.0":
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/randomstring/-/randomstring-1.3.0.tgz#2953e8de350c27c10eb1aa011fbca8d88c327d79"
|
|
||||||
integrity sha512-kCP61wludjY7oNUeFiMxfswHB3Wn/aC03Cu82oQsNTO6OCuhVN/rCbBs68Cq6Nkgjmp2Sh3Js6HearJPkk7KQA==
|
|
||||||
|
|
||||||
"@types/range-parser@*":
|
"@types/range-parser@*":
|
||||||
version "1.2.4"
|
version "1.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
|
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
|
||||||
@@ -6432,17 +6412,7 @@ browserslist-to-esbuild@^1.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
browserslist "^4.17.3"
|
browserslist "^4.17.3"
|
||||||
|
|
||||||
browserslist@^4.17.3, browserslist@^4.24.0:
|
browserslist@^4.17.3, browserslist@^4.24.0, browserslist@^4.25.1:
|
||||||
version "4.24.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b"
|
|
||||||
integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==
|
|
||||||
dependencies:
|
|
||||||
caniuse-lite "^1.0.30001688"
|
|
||||||
electron-to-chromium "^1.5.73"
|
|
||||||
node-releases "^2.0.19"
|
|
||||||
update-browserslist-db "^1.1.1"
|
|
||||||
|
|
||||||
browserslist@^4.25.1:
|
|
||||||
version "4.25.1"
|
version "4.25.1"
|
||||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.1.tgz#ba9e8e6f298a1d86f829c9b975e07948967bb111"
|
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.1.tgz#ba9e8e6f298a1d86f829c9b975e07948967bb111"
|
||||||
integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==
|
integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==
|
||||||
@@ -6585,12 +6555,7 @@ camelize@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
|
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
|
||||||
integrity "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg=="
|
integrity "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg=="
|
||||||
|
|
||||||
caniuse-lite@^1.0.30001688:
|
caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001726:
|
||||||
version "1.0.30001699"
|
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz#a102cf330d153bf8c92bfb5be3cd44c0a89c8c12"
|
|
||||||
integrity sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==
|
|
||||||
|
|
||||||
caniuse-lite@^1.0.30001726:
|
|
||||||
version "1.0.30001727"
|
version "1.0.30001727"
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz#22e9706422ad37aa50556af8c10e40e2d93a8b85"
|
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz#22e9706422ad37aa50556af8c10e40e2d93a8b85"
|
||||||
integrity sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==
|
integrity sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==
|
||||||
@@ -8007,16 +7972,11 @@ ejs@^3.1.10, ejs@^3.1.6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
jake "^10.8.5"
|
jake "^10.8.5"
|
||||||
|
|
||||||
electron-to-chromium@^1.5.173:
|
electron-to-chromium@^1.5.173, electron-to-chromium@^1.5.73:
|
||||||
version "1.5.182"
|
version "1.5.182"
|
||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz#4ab73104f893938acb3ab9c28d7bec170c116b3e"
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz#4ab73104f893938acb3ab9c28d7bec170c116b3e"
|
||||||
integrity sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==
|
integrity sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==
|
||||||
|
|
||||||
electron-to-chromium@^1.5.73:
|
|
||||||
version "1.5.99"
|
|
||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.99.tgz#4817c7526d71b66e6c56c3e5231fe1113653a85d"
|
|
||||||
integrity sha512-77c/+fCyL2U+aOyqfIFi89wYLBeSTCs55xCZL0oFH0KjqsvSvyh6AdQ+UIl1vgpnQQE6g+/KK8hOIupH6VwPtg==
|
|
||||||
|
|
||||||
email-providers@^1.14.0:
|
email-providers@^1.14.0:
|
||||||
version "1.14.0"
|
version "1.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/email-providers/-/email-providers-1.14.0.tgz#a353f56390f9a8b42ba1843a1701c1f5fcd332ee"
|
resolved "https://registry.yarnpkg.com/email-providers/-/email-providers-1.14.0.tgz#a353f56390f9a8b42ba1843a1701c1f5fcd332ee"
|
||||||
@@ -9860,14 +9820,7 @@ is-callable@^1.1.3, is-callable@^1.2.7:
|
|||||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
|
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
|
||||||
integrity "sha1-O8KoXqdC2eNiBdys3XLKH9xRsFU= sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
|
integrity "sha1-O8KoXqdC2eNiBdys3XLKH9xRsFU= sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
|
||||||
|
|
||||||
is-core-module@^2.13.0, is-core-module@^2.15.1:
|
is-core-module@^2.13.0, is-core-module@^2.15.1, is-core-module@^2.16.0:
|
||||||
version "2.16.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.0.tgz#6c01ffdd5e33c49c1d2abfa93334a85cb56bd81c"
|
|
||||||
integrity sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==
|
|
||||||
dependencies:
|
|
||||||
hasown "^2.0.2"
|
|
||||||
|
|
||||||
is-core-module@^2.16.0:
|
|
||||||
version "2.16.1"
|
version "2.16.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
|
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
|
||||||
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
|
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
|
||||||
@@ -13144,20 +13097,13 @@ quick-temp@^0.1.8:
|
|||||||
rimraf "^2.5.4"
|
rimraf "^2.5.4"
|
||||||
underscore.string "~3.3.4"
|
underscore.string "~3.3.4"
|
||||||
|
|
||||||
randombytes@2.1.0, randombytes@^2.1.0:
|
randombytes@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||||
integrity "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo= sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="
|
integrity "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo= sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.1.0"
|
safe-buffer "^5.1.0"
|
||||||
|
|
||||||
randomstring@1.3.1:
|
|
||||||
version "1.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/randomstring/-/randomstring-1.3.1.tgz#11a494a9d51b320dd8694a3e0ee7d77b0f8e477c"
|
|
||||||
integrity sha512-lgXZa80MUkjWdE7g2+PZ1xDLzc7/RokXVEQOv5NN2UOTChW1I8A9gha5a9xYBOqgaSoI6uJikDmCU8PyRdArRQ==
|
|
||||||
dependencies:
|
|
||||||
randombytes "2.1.0"
|
|
||||||
|
|
||||||
rate-limiter-flexible@^2.4.2:
|
rate-limiter-flexible@^2.4.2:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/rate-limiter-flexible/-/rate-limiter-flexible-2.4.2.tgz#2a219cc473f015142fd8fb599371223d730decbd"
|
resolved "https://registry.yarnpkg.com/rate-limiter-flexible/-/rate-limiter-flexible-2.4.2.tgz#2a219cc473f015142fd8fb599371223d730decbd"
|
||||||
@@ -13690,16 +13636,7 @@ resolve.exports@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e"
|
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e"
|
||||||
integrity "sha1-waACjC0WbsL799BkRYSSfnbnQA4= sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg=="
|
integrity "sha1-waACjC0WbsL799BkRYSSfnbnQA4= sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg=="
|
||||||
|
|
||||||
resolve@^1.1.6, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.4:
|
resolve@^1.1.6, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.10, resolve@^1.22.4:
|
||||||
version "1.22.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34"
|
|
||||||
integrity "sha1-HcQN9GVUza+JSKSGoQ9roeICbDQ= sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg=="
|
|
||||||
dependencies:
|
|
||||||
is-core-module "^2.13.0"
|
|
||||||
path-parse "^1.0.7"
|
|
||||||
supports-preserve-symlinks-flag "^1.0.0"
|
|
||||||
|
|
||||||
resolve@^1.22.10:
|
|
||||||
version "1.22.10"
|
version "1.22.10"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
|
||||||
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
|
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
|
||||||
@@ -15330,15 +15267,7 @@ upath@^1.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
|
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
|
||||||
integrity "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ= sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
|
integrity "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ= sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
|
||||||
|
|
||||||
update-browserslist-db@^1.1.1:
|
update-browserslist-db@^1.1.1, update-browserslist-db@^1.1.3:
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz#97e9c96ab0ae7bcac08e9ae5151d26e6bc6b5580"
|
|
||||||
integrity sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==
|
|
||||||
dependencies:
|
|
||||||
escalade "^3.2.0"
|
|
||||||
picocolors "^1.1.1"
|
|
||||||
|
|
||||||
update-browserslist-db@^1.1.3:
|
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
|
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
|
||||||
integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
|
integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
|
||||||
|
|||||||
Reference in New Issue
Block a user