From 6462f5bf667d82274ea748ae7fd46a66c36b7ca7 Mon Sep 17 00:00:00 2001 From: Andrew Plummer Date: Tue, 10 Dec 2024 14:53:55 -0500 Subject: [PATCH] removed bedrock/config in favor of node --env-file (#251) --- services/api/.env | 2 +- services/api/.env.production | 5 +++-- services/api/.env.staging | 5 +++-- services/api/__mocks__/twilio.js | 3 +-- services/api/package.json | 15 +++++++-------- services/api/scripts/fixtures/reload | 3 +-- services/api/src/app.js | 9 ++++----- services/api/src/index.js | 15 ++++----------- services/api/src/routes/auth/apple/utils.js | 3 +-- services/api/src/routes/auth/google/utils.js | 3 +-- services/api/src/routes/auth/passkey/utils.js | 7 ++----- services/api/src/routes/auth/totp/utils.js | 3 +-- services/api/src/utils/auth/tokens.js | 3 +-- services/api/src/utils/csv.js | 3 +-- services/api/src/utils/database.js | 7 ++++--- services/api/src/utils/messaging/mailer.js | 8 +------- services/api/src/utils/messaging/sms.js | 10 +--------- services/api/src/utils/messaging/utils.js | 3 +-- .../api/src/utils/middleware/__tests__/tokens.js | 12 ++++++------ services/api/src/utils/middleware/authenticate.js | 3 +-- .../api/src/utils/middleware/error-handler.js | 4 ++-- services/api/src/utils/middleware/organization.js | 3 +-- services/api/src/utils/openapi.js | 5 ++--- services/api/src/utils/uploads.js | 10 ++++------ services/api/yarn.lock | 14 ++++---------- 25 files changed, 58 insertions(+), 100 deletions(-) diff --git a/services/api/.env b/services/api/.env index c689f8f0..8a527fdd 100644 --- a/services/api/.env +++ b/services/api/.env @@ -5,7 +5,7 @@ SERVER_PORT=2300 # Main DB Config MONGO_URI=mongodb://localhost/bedrock_dev -MONGO_DEBUG=false +MONGO_DEBUG= # Default admin account for dashboard login ADMIN_NAME=Marlon Brando diff --git a/services/api/.env.production b/services/api/.env.production index a6a21abf..e998a5a3 100644 --- a/services/api/.env.production +++ b/services/api/.env.production @@ -1,2 +1,3 @@ -export MONGO_URI=mongodb://localhost/bedrock_production -export UPLOADS_GCS_BUCKET=bedrock-production-uploads \ No newline at end of file +# This file is for local use only. Do NOT put secrets in here. +MONGO_URI=mongodb://localhost/bedrock_production +UPLOADS_GCS_BUCKET=bedrock-production-uploads \ No newline at end of file diff --git a/services/api/.env.staging b/services/api/.env.staging index 52a322cb..a4bb5c10 100644 --- a/services/api/.env.staging +++ b/services/api/.env.staging @@ -1,2 +1,3 @@ -export MONGO_URI=mongodb://localhost/bedrock_staging -export UPLOADS_GCS_BUCKET=bedrock-staging-uploads \ No newline at end of file +# This file is for local use only. Do NOT put secrets in here. +MONGO_URI=mongodb://localhost/bedrock_staging +UPLOADS_GCS_BUCKET=bedrock-staging-uploads \ No newline at end of file diff --git a/services/api/__mocks__/twilio.js b/services/api/__mocks__/twilio.js index 686ee014..d02faf72 100644 --- a/services/api/__mocks__/twilio.js +++ b/services/api/__mocks__/twilio.js @@ -1,8 +1,7 @@ const crypto = require('crypto'); -const config = require('@bedrockio/config'); const twilio = jest.requireActual('twilio'); -const AUTH_TOKEN = config.get('TWILIO_AUTH_TOKEN'); +const { AUTH_TOKEN } = process.env; let sentMessages; let createdRooms; diff --git a/services/api/package.json b/services/api/package.json index 2dd4a340..89b6f161 100644 --- a/services/api/package.json +++ b/services/api/package.json @@ -7,22 +7,21 @@ "node": ">=20" }, "scripts": { - "start": "node --watch src/index.js", + "start": "node --env-file=.env --watch src/index.js", "debug": "MONGO_DEBUG=true yarn start", - "staging": "source .env.staging && node --watch src/index.js", - "production": "source .env.production && node --watch src/index.js", - "start:production": "node src/index", + "staging": "node --env-file=.env --env-file=.env.staging --watch src/index.js", + "production": "node --env-file=.env --env-file=.env.production --watch src/index.js", + "start:production": "node --env-file=.env src/index", "lint": "eslint", - "test": "jest", - "test:watch": "jest --watch -i", + "test": "node --env-file=.env ./node_modules/.bin/jest", + "test:watch": "node --env-file=.env ./node_modules/.bin/jest --watch -i", "fixtures:load": "./scripts/fixtures/load", "fixtures:reload": "./scripts/fixtures/reload", "fixtures:export": "./scripts/fixtures/export", "docs:generate": "./scripts/docs/generate" }, "dependencies": { - "@bedrockio/config": "^2.2.3", - "@bedrockio/fixtures": "^1.2.5", + "@bedrockio/fixtures": "^1.3.0", "@bedrockio/logger": "^1.0.8", "@bedrockio/model": "^0.7.3", "@bedrockio/yada": "^1.2.3", diff --git a/services/api/scripts/fixtures/reload b/services/api/scripts/fixtures/reload index 3e9671be..c9229b87 100755 --- a/services/api/scripts/fixtures/reload +++ b/services/api/scripts/fixtures/reload @@ -1,6 +1,5 @@ #!/usr/bin/env node -const config = require('@bedrockio/config'); const logger = require('@bedrockio/logger'); const { initialize } = require('../../src/utils/database'); const { loadFixtures } = require('../../src/utils/fixtures'); @@ -9,7 +8,7 @@ const readline = require('readline'); // Ensure models are loaded. require('../../src/models'); -const ENV_NAME = config.get('ENV_NAME'); +const { ENV_NAME } = process.env; const rl = readline.createInterface({ input: process.stdin, diff --git a/services/api/src/app.js b/services/api/src/app.js index 74a6cd40..dfe2bda0 100644 --- a/services/api/src/app.js +++ b/services/api/src/app.js @@ -9,12 +9,11 @@ const serializeMiddleware = require('./utils/middleware/serialize'); const organizationMiddleware = require('./utils/middleware/organization'); const { applicationMiddleware } = require('./utils/middleware/application'); const { loadDefinition } = require('./utils/openapi'); +const logger = require('@bedrockio/logger'); const Sentry = require('@sentry/node'); const routes = require('./routes'); -const config = require('@bedrockio/config'); -const logger = require('@bedrockio/logger'); -const ENV_NAME = config.get('ENV_NAME'); +const { ENV_NAME, SENTRY_DSN } = process.env; const app = new Koa(); @@ -74,9 +73,9 @@ app.on('error', (err, ctx) => { } }); -if (config.has('SENTRY_DSN')) { +if (SENTRY_DSN) { Sentry.init({ - dsn: config.get('SENTRY_DSN'), + dsn: SENTRY_DSN, environment: ENV_NAME, }); } diff --git a/services/api/src/index.js b/services/api/src/index.js index 4704e714..a4c39a31 100644 --- a/services/api/src/index.js +++ b/services/api/src/index.js @@ -1,13 +1,10 @@ const logger = require('@bedrockio/logger'); -const config = require('@bedrockio/config'); const { initialize } = require('./utils/database'); const { loadFixtures } = require('./utils/fixtures'); const app = require('./app'); -const ENV_NAME = config.get('ENV_NAME'); -const PORT = config.get('SERVER_PORT', 'number'); -const HOST = config.get('SERVER_HOST'); +const { ENV_NAME, SERVER_PORT, SERVER_HOST, APP_NAME, ADMIN_EMAIL, ADMIN_PASSWORD } = process.env; if (process.env.NODE_ENV === 'production') { logger.setupGoogleCloud({ @@ -24,15 +21,11 @@ module.exports = (async () => { if (ENV_NAME === 'development') { await loadFixtures(); } - app.listen(PORT, HOST, () => { - logger.info(`Started on port //${HOST}:${PORT}`); + app.listen(SERVER_PORT, SERVER_HOST, () => { + logger.info(`Started on port //${SERVER_HOST}:${SERVER_PORT}`); if (ENV_NAME === 'development') { logger.info('-----------------------------------------------------------------'); - logger.info( - `${config.get('APP_NAME')} Admin Login ${config.get('ADMIN_EMAIL')}:${config.get( - 'ADMIN_PASSWORD' - )} (dev env only)` - ); + logger.info(`${APP_NAME} Admin Login ${ADMIN_EMAIL}:${ADMIN_PASSWORD} (dev env only)`); logger.info('-----------------------------------------------------------------'); } }); diff --git a/services/api/src/routes/auth/apple/utils.js b/services/api/src/routes/auth/apple/utils.js index 19cd9c42..21990673 100644 --- a/services/api/src/routes/auth/apple/utils.js +++ b/services/api/src/routes/auth/apple/utils.js @@ -1,9 +1,8 @@ const verifyAppleToken = require('verify-apple-id-token').default; -const config = require('@bedrockio/config'); const { clearAuthenticators } = require('../../../utils/auth/authenticators'); -const APPLE_SERVICE_ID = config.get('APPLE_SERVICE_ID'); +const { APPLE_SERVICE_ID } = process.env; async function verifyToken(token) { const payload = await verifyAppleToken({ diff --git a/services/api/src/routes/auth/google/utils.js b/services/api/src/routes/auth/google/utils.js index 2f7b46f6..43861dea 100644 --- a/services/api/src/routes/auth/google/utils.js +++ b/services/api/src/routes/auth/google/utils.js @@ -1,10 +1,9 @@ const { OAuth2Client } = require('google-auth-library'); -const config = require('@bedrockio/config'); const { clearAuthenticators } = require('../../../utils/auth/authenticators'); const client = new OAuth2Client(); -const GOOGLE_CLIENT_ID = config.get('GOOGLE_CLIENT_ID'); +const { GOOGLE_CLIENT_ID } = process.env; async function verifyToken(token) { const ticket = await client.verifyIdToken({ diff --git a/services/api/src/routes/auth/passkey/utils.js b/services/api/src/routes/auth/passkey/utils.js index 8ad499f6..bf26dd02 100644 --- a/services/api/src/routes/auth/passkey/utils.js +++ b/services/api/src/routes/auth/passkey/utils.js @@ -1,10 +1,7 @@ const SimpleWebAuthn = require('@simplewebauthn/server'); -const config = require('@bedrockio/config'); - const { clearAuthenticators, getRequiredAuthenticator } = require('../../../utils/auth/authenticators'); -const APP_NAME = config.get('APP_NAME'); -const APP_URL = config.get('APP_URL'); +const { APP_NAME, APP_URL } = process.env; // Human-readable app name. const rpName = APP_NAME; @@ -14,7 +11,7 @@ const rpName = APP_NAME; const rpID = new URL(APP_URL).hostname; // The URL at which registrations and authentications should occur -const origin = config.get('APP_URL'); +const origin = APP_URL; async function generateRegistrationOptions(user) { // Only allow a single passkey at a time. diff --git a/services/api/src/routes/auth/totp/utils.js b/services/api/src/routes/auth/totp/utils.js index 541746a4..2a5eeccc 100644 --- a/services/api/src/routes/auth/totp/utils.js +++ b/services/api/src/routes/auth/totp/utils.js @@ -1,9 +1,8 @@ const speakeasy = require('speakeasy'); -const config = require('@bedrockio/config'); const { clearAuthenticators, getRequiredAuthenticator } = require('../../../utils/auth/authenticators'); -const APP_NAME = config.get('APP_NAME'); +const { APP_NAME } = process.env; function generateTotp() { const secret = createSecret(); diff --git a/services/api/src/utils/auth/tokens.js b/services/api/src/utils/auth/tokens.js index bacec913..0b3e7634 100644 --- a/services/api/src/utils/auth/tokens.js +++ b/services/api/src/utils/auth/tokens.js @@ -1,8 +1,7 @@ const jwt = require('jsonwebtoken'); -const config = require('@bedrockio/config'); const { nanoid } = require('nanoid'); -const JWT_SECRET = config.get('JWT_SECRET'); +const { JWT_SECRET } = process.env; // All expires are expressed in seconds (jwt spec) const expiresIn = { diff --git a/services/api/src/utils/csv.js b/services/api/src/utils/csv.js index 0db34e7c..68898d49 100644 --- a/services/api/src/utils/csv.js +++ b/services/api/src/utils/csv.js @@ -2,7 +2,6 @@ const { PassThrough } = require('stream'); const csv = require('fast-csv'); const yd = require('@bedrockio/yada'); -const config = require('@bedrockio/config'); const mongoose = require('mongoose'); const { get, startCase } = require('lodash'); @@ -10,7 +9,7 @@ const { serializeObject } = require('./serialize'); const formatter = Intl.NumberFormat('us'); -const API_URL = config.get('API_URL'); +const { API_URL } = process.env; const DEFAULT_OPTIONS = { readableHeaders: true, diff --git a/services/api/src/utils/database.js b/services/api/src/utils/database.js index 7bfd777e..f115280a 100644 --- a/services/api/src/utils/database.js +++ b/services/api/src/utils/database.js @@ -1,7 +1,8 @@ const mongoose = require('mongoose'); -const config = require('@bedrockio/config'); const logger = require('@bedrockio/logger'); +const { MONGO_URI, MONGO_DEBUG } = process.env; + mongoose.Promise = Promise; // https://mongoosejs.com/docs/migrating_to_6.html#no-more-deprecation-warning-options @@ -25,9 +26,9 @@ exports.flags = flags; exports.initialize = async function initialize() { mongoose.set('strictQuery', false); - await mongoose.connect(config.get('MONGO_URI'), flags); + await mongoose.connect(MONGO_URI, flags); - if (config.get('MONGO_DEBUG', 'boolean')) { + if (MONGO_DEBUG) { mongoose.set('debug', true); } diff --git a/services/api/src/utils/messaging/mailer.js b/services/api/src/utils/messaging/mailer.js index f1f54351..e47d638b 100644 --- a/services/api/src/utils/messaging/mailer.js +++ b/services/api/src/utils/messaging/mailer.js @@ -5,15 +5,9 @@ const htmlToText = require('html-to-text'); const { loadTemplate, interpolate, escapeHtml } = require('./utils'); -const config = require('@bedrockio/config'); const logger = require('@bedrockio/logger'); -const ENV_NAME = config.get('ENV_NAME'); -const APP_NAME = config.get('APP_NAME'); -const POSTMARK_FROM = config.get('POSTMARK_FROM'); -const POSTMARK_API_KEY = config.get('POSTMARK_API_KEY'); -const POSTMARK_DEV_EMAIL = config.get('POSTMARK_DEV_EMAIL'); -const POSTMARK_WEBHOOK_KEY = config.get('POSTMARK_WEBHOOK_KEY'); +const { ENV_NAME, APP_NAME, POSTMARK_API_KEY, POSTMARK_FROM, POSTMARK_DEV_EMAIL, POSTMARK_WEBHOOK_KEY } = process.env; const TEMPLATE_DIR = path.join(__dirname, '../../emails'); diff --git a/services/api/src/utils/messaging/sms.js b/services/api/src/utils/messaging/sms.js index ffd23110..d5bb16e6 100644 --- a/services/api/src/utils/messaging/sms.js +++ b/services/api/src/utils/messaging/sms.js @@ -1,18 +1,10 @@ const path = require('path'); const twilio = require('twilio'); -const config = require('@bedrockio/config'); const logger = require('@bedrockio/logger'); const { interpolate, loadTemplate } = require('./utils'); -const API_URL = config.get('API_URL'); -const ENV_NAME = config.get('ENV_NAME'); - -const AUTH_TOKEN = config.get('TWILIO_AUTH_TOKEN'); -const ACCOUNT_SID = config.get('TWILIO_ACCOUNT_SID'); -const TEST_NUMBER = config.get('TWILIO_TEST_NUMBER'); -const FROM_NUMBER = config.get('TWILIO_FROM_NUMBER'); -const WEBHOOK_URL = config.get('TWILIO_WEBHOOK_URL'); +const { API_URL, ENV_NAME, AUTH_TOKEN, ACCOUNT_SID, TEST_NUMBER, FROM_NUMBER, WEBHOOK_URL } = process.env; const TEMPLATE_DIR = path.join(__dirname, '../../sms'); diff --git a/services/api/src/utils/messaging/utils.js b/services/api/src/utils/messaging/utils.js index 4e605af1..d81505d4 100644 --- a/services/api/src/utils/messaging/utils.js +++ b/services/api/src/utils/messaging/utils.js @@ -2,12 +2,11 @@ const fs = require('fs/promises'); const path = require('path'); const Mustache = require('mustache'); const frontmatter = require('front-matter'); -const config = require('@bedrockio/config'); const { memoize } = require('lodash'); // Environment vars -const ENV = config.getAll(); +const ENV = process.env; // Mustache utils diff --git a/services/api/src/utils/middleware/__tests__/tokens.js b/services/api/src/utils/middleware/__tests__/tokens.js index 2582a9a4..4a423582 100644 --- a/services/api/src/utils/middleware/__tests__/tokens.js +++ b/services/api/src/utils/middleware/__tests__/tokens.js @@ -1,6 +1,6 @@ const jwt = require('jsonwebtoken'); -const config = require('@bedrockio/config'); +const { JWT_SECRET } = process.env; const { validateToken } = require('../tokens'); const { context } = require('../../testing'); @@ -53,14 +53,14 @@ describe('validateToken', () => { it('should fail if expired', async () => { const middleware = validateToken(); - const token = jwt.sign({ kid: 'user' }, config.get('JWT_SECRET'), { expiresIn: 0 }); + const token = jwt.sign({ kid: 'user' }, JWT_SECRET, { expiresIn: 0 }); const ctx = context({ headers: { authorization: `Bearer ${token}` } }); await expect(middleware(ctx)).rejects.toHaveProperty('message', 'jwt expired'); }); it('should work with valid secret and not expired', async () => { const middleware = validateToken(); - const token = jwt.sign({ kid: 'user', attribute: 'value' }, config.get('JWT_SECRET')); + const token = jwt.sign({ kid: 'user', attribute: 'value' }, JWT_SECRET); const ctx = context({ headers: { authorization: `Bearer ${token}` } }); await middleware(ctx, () => { expect(ctx.state.jwt.attribute).toBe('value'); @@ -69,7 +69,7 @@ describe('validateToken', () => { it('should only validate the token once when called multiple times', async () => { const middleware = validateToken(); - const token = jwt.sign({ kid: 'user', attribute: 'value' }, config.get('JWT_SECRET')); + const token = jwt.sign({ kid: 'user', attribute: 'value' }, JWT_SECRET); const ctx = context({ headers: { authorization: `Bearer ${token}` } }); let tmp; @@ -92,7 +92,7 @@ describe('validateToken', () => { describe('optional validation', () => { it('should validateToken when token exists', async () => { const middleware = validateToken({ optional: true }); - const token = jwt.sign({ kid: 'user', attribute: 'value' }, config.get('JWT_SECRET')); + const token = jwt.sign({ kid: 'user', attribute: 'value' }, JWT_SECRET); const ctx = context({ headers: { authorization: `Bearer ${token}` } }); await middleware(ctx, () => { expect(ctx.state.jwt.attribute).toBe('value'); @@ -111,7 +111,7 @@ describe('validateToken', () => { const optional = validateToken({ optional: true }); const required = validateToken(); - const token = jwt.sign({ kid: 'user', attribute: 'value' }, config.get('JWT_SECRET')); + const token = jwt.sign({ kid: 'user', attribute: 'value' }, JWT_SECRET); const ctx = context({ headers: { authorization: `Bearer ${token}` } }); await optional(ctx, () => {}); diff --git a/services/api/src/utils/middleware/authenticate.js b/services/api/src/utils/middleware/authenticate.js index d039e5c5..57203712 100644 --- a/services/api/src/utils/middleware/authenticate.js +++ b/services/api/src/utils/middleware/authenticate.js @@ -1,9 +1,8 @@ const { validateToken } = require('./tokens'); const { User } = require('../../models'); const compose = require('koa-compose'); -const config = require('@bedrockio/config'); -const ENV_NAME = config.get('ENV_NAME'); +const { ENV_NAME } = process.env; function authenticate(options = {}) { const { optional } = options; diff --git a/services/api/src/utils/middleware/error-handler.js b/services/api/src/utils/middleware/error-handler.js index 84973e83..bdef6aa9 100644 --- a/services/api/src/utils/middleware/error-handler.js +++ b/services/api/src/utils/middleware/error-handler.js @@ -1,6 +1,6 @@ -const config = require('@bedrockio/config'); const { isSchemaError } = require('@bedrockio/yada'); -const ENV_NAME = config.get('ENV_NAME'); + +const { ENV_NAME } = process.env; async function errorHandler(ctx, next) { try { diff --git a/services/api/src/utils/middleware/organization.js b/services/api/src/utils/middleware/organization.js index 8137c2f2..d211c2d4 100644 --- a/services/api/src/utils/middleware/organization.js +++ b/services/api/src/utils/middleware/organization.js @@ -1,7 +1,6 @@ const { Organization } = require('../../models'); -const config = require('@bedrockio/config'); -const DEFAULT_ORGANIZATION_NAME = config.get('DEFAULT_ORGANIZATION_NAME'); +const { DEFAULT_ORGANIZATION_NAME } = process.env; async function organization(ctx, next) { const identifier = ctx.request.get('organization') || ''; diff --git a/services/api/src/utils/openapi.js b/services/api/src/utils/openapi.js index 995d5897..25d8c31e 100644 --- a/services/api/src/utils/openapi.js +++ b/services/api/src/utils/openapi.js @@ -3,8 +3,6 @@ const path = require('path'); const crypto = require('crypto'); const { Stream } = require('stream'); const mongoose = require('mongoose'); -const config = require('@bedrockio/config'); - const { get, set, merge, isEmpty, without, camelCase, kebabCase, startCase } = require('lodash'); const pluralize = mongoose.pluralize(); @@ -13,6 +11,7 @@ const PACKAGE_FILE = path.resolve(__dirname, '../../package.json'); const DEFINITION_FILE = path.resolve(__dirname, '../../openapi.json'); const EDITABLE_FIELDS = ['title', 'summary', 'description']; +const { API_URL } = process.env; let definition; @@ -63,7 +62,7 @@ async function generateDefinition() { }, servers: [ { - url: config.get('API_URL'), + url: API_URL, }, ], paths: generatePaths(require('../routes')), diff --git a/services/api/src/utils/uploads.js b/services/api/src/utils/uploads.js index 459bf45d..b13c1a38 100644 --- a/services/api/src/utils/uploads.js +++ b/services/api/src/utils/uploads.js @@ -4,19 +4,17 @@ const path = require('path'); const https = require('https'); const { copyFile, writeFile } = require('fs/promises'); -const config = require('@bedrockio/config'); const logger = require('@bedrockio/logger'); const mime = require('mime-types'); const Readable = require('stream').Readable; const { Storage } = require('@google-cloud/storage'); const { Upload } = require('../models'); -const BUCKET_NAME = config.get('UPLOADS_GCS_BUCKET'); -const UPLOADS_STORE = config.get('UPLOADS_STORE'); +const { UPLOADS_STORE, UPLOADS_GCS_BUCKET } = process.env; const storage = new Storage(); -const bucket = storage.bucket(BUCKET_NAME); +const bucket = storage.bucket(UPLOADS_GCS_BUCKET); async function createUploads(arg, options) { const files = Array.isArray(arg) ? arg : [arg]; @@ -81,7 +79,7 @@ async function uploadGcs(file, upload) { const destination = getUploadFilename(upload); const gcsFile = bucket.file(destination); - logger.info('Uploading gcs %s -> gs://%s/%s', filename, BUCKET_NAME, destination); + logger.info('Uploading gcs %s -> gs://%s/%s', filename, UPLOADS_GCS_BUCKET, destination); if (buffer) { await gcsFile.save(buffer); @@ -126,7 +124,7 @@ function getUploadFilename(upload) { } function getGcsFile(upload) { - const bucket = storage.bucket(BUCKET_NAME); + const bucket = storage.bucket(UPLOADS_GCS_BUCKET); return bucket.file(getUploadFilename(upload)); } diff --git a/services/api/yarn.lock b/services/api/yarn.lock index cb27ee66..ae297e81 100644 --- a/services/api/yarn.lock +++ b/services/api/yarn.lock @@ -298,17 +298,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@bedrockio/config@^2.2.2", "@bedrockio/config@^2.2.3": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@bedrockio/config/-/config-2.2.3.tgz#bac37d12e36a99ec16668c8b5d1e05dec9658fa9" - integrity sha512-jfOcZIs63S0GaWQjh5vVIISr4b2vA0CWgm630N0FDB6wlW+O0Fsjox92Agx5nggVpSnNYWqzjuKaUb5RY3/ECw== - -"@bedrockio/fixtures@^1.2.5": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@bedrockio/fixtures/-/fixtures-1.2.5.tgz#43aed9428d49bcec25a60a0fb39cb70643db7025" - integrity sha512-4gt5dZQuDT8Eu2IJK92XbhpCpL/9Vyc1esypjuB5O8Mt/SEKwL8R4Hjj50WcJ8qfAohLJIU7KIQOFUDR/9YVkg== +"@bedrockio/fixtures@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@bedrockio/fixtures/-/fixtures-1.3.0.tgz#80b2154a0c4f858b2628c4f708caf846e6ab4f2d" + integrity sha512-JrJEsIULg+0nXVZZyFAE4DKsMxz3MMbXvNXJowoC8rDwVK2ZBXdT+pe7biDlKoNmsRGdzosIBM24EUgFEo1vmg== dependencies: - "@bedrockio/config" "^2.2.2" "@bedrockio/logger" "^1.0.3" glob "^8.1.0" jszip "^3.10.1"