mirror of
https://github.com/directus/directus.git
synced 2026-01-23 18:18:03 -05:00
Switch to exifr for image metadata extraction (#6922)
* Switch to exifr for image metadata extraction * Fix migrations on pg * Prevent double divider Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
@@ -98,14 +98,13 @@
|
||||
"dotenv": "^10.0.0",
|
||||
"eventemitter2": "^6.4.3",
|
||||
"execa": "^5.1.1",
|
||||
"exif-reader": "^1.0.3",
|
||||
"exifr": "^7.1.2",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.17.2",
|
||||
"fs-extra": "^10.0.0",
|
||||
"grant": "^5.4.14",
|
||||
"graphql": "^15.5.0",
|
||||
"graphql-compose": "^9.0.1",
|
||||
"icc": "^2.0.0",
|
||||
"inquirer": "^8.1.1",
|
||||
"joi": "^17.3.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { Knex } from 'knex';
|
||||
|
||||
// Change image metadata structure to match the output from 'exifr'
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
const files = await knex
|
||||
.select<{ id: number; metadata: string }[]>('id', 'metadata')
|
||||
.from('directus_files')
|
||||
.whereNotNull('metadata');
|
||||
|
||||
for (const { id, metadata } of files) {
|
||||
let prevMetadata;
|
||||
|
||||
try {
|
||||
prevMetadata = JSON.parse(metadata);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update only required if metadata has 'exif' data
|
||||
if (prevMetadata.exif) {
|
||||
// Get all data from 'exif' and rename the following keys:
|
||||
// - 'image' to 'ifd0'
|
||||
// - 'thumbnail to 'ifd1'
|
||||
// - 'interoperability' to 'interop'
|
||||
const newMetadata = prevMetadata.exif;
|
||||
|
||||
if (newMetadata.image) {
|
||||
newMetadata.ifd0 = newMetadata.image;
|
||||
delete newMetadata.image;
|
||||
}
|
||||
if (newMetadata.thumbnail) {
|
||||
newMetadata.ifd1 = newMetadata.thumbnail;
|
||||
delete newMetadata.thumbnail;
|
||||
}
|
||||
if (newMetadata.interoperability) {
|
||||
newMetadata.interop = newMetadata.interoperability;
|
||||
delete newMetadata.interoperability;
|
||||
}
|
||||
if (prevMetadata.icc) {
|
||||
newMetadata.icc = prevMetadata.icc;
|
||||
}
|
||||
if (prevMetadata.iptc) {
|
||||
newMetadata.iptc = prevMetadata.iptc;
|
||||
}
|
||||
|
||||
await knex('directus_files')
|
||||
.update({ metadata: JSON.stringify(newMetadata) })
|
||||
.where({ id });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
const files = await knex
|
||||
.select<{ id: number; metadata: string }[]>('id', 'metadata')
|
||||
.from('directus_files')
|
||||
.whereNotNull('metadata')
|
||||
.whereNot('metadata', '{}');
|
||||
|
||||
for (const { id, metadata } of files) {
|
||||
const prevMetadata = JSON.parse(metadata);
|
||||
|
||||
// Update only required if metadata has keys other than 'icc' and 'iptc'
|
||||
if (Object.keys(prevMetadata).filter((key) => key !== 'icc' && key !== 'iptc').length > 0) {
|
||||
// Put all data under 'exif' and rename/move keys afterwards
|
||||
const newMetadata: { exif: Record<string, unknown>; icc?: unknown; iptc?: unknown } = { exif: prevMetadata };
|
||||
|
||||
if (newMetadata.exif.ifd0) {
|
||||
newMetadata.exif.image = newMetadata.exif.ifd0;
|
||||
delete newMetadata.exif.ifd0;
|
||||
}
|
||||
if (newMetadata.exif.ifd1) {
|
||||
newMetadata.exif.thumbnail = newMetadata.exif.ifd1;
|
||||
delete newMetadata.exif.ifd1;
|
||||
}
|
||||
if (newMetadata.exif.interop) {
|
||||
newMetadata.exif.interoperability = newMetadata.exif.interop;
|
||||
delete newMetadata.exif.interop;
|
||||
}
|
||||
if (newMetadata.exif.icc) {
|
||||
newMetadata.icc = newMetadata.exif.icc;
|
||||
delete newMetadata.exif.icc;
|
||||
}
|
||||
if (newMetadata.exif.iptc) {
|
||||
newMetadata.iptc = newMetadata.exif.iptc;
|
||||
delete newMetadata.exif.iptc;
|
||||
}
|
||||
|
||||
await knex('directus_files')
|
||||
.update({ metadata: JSON.stringify(newMetadata) })
|
||||
.where({ id });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import formatTitle from '@directus/format-title';
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
import parseEXIF from 'exif-reader';
|
||||
import { parse as parseICC } from 'icc';
|
||||
import exifr from 'exifr';
|
||||
import { clone } from 'lodash';
|
||||
import { extension } from 'mime-types';
|
||||
import path from 'path';
|
||||
@@ -13,7 +12,6 @@ import { ForbiddenException, ServiceUnavailableException } from '../exceptions';
|
||||
import logger from '../logger';
|
||||
import storage from '../storage';
|
||||
import { AbstractServiceOptions, File, PrimaryKey } from '../types';
|
||||
import parseIPTC from '../utils/parse-iptc';
|
||||
import { toArray } from '@directus/shared/utils';
|
||||
import { ItemsService, MutationOptions } from './items';
|
||||
|
||||
@@ -86,37 +84,30 @@ export class FilesService extends ItemsService {
|
||||
payload.height = meta.height;
|
||||
}
|
||||
|
||||
payload.filesize = meta.size;
|
||||
payload.metadata = {};
|
||||
|
||||
if (meta.icc) {
|
||||
try {
|
||||
payload.metadata.icc = parseICC(meta.icc);
|
||||
} catch (err) {
|
||||
logger.warn(`Couldn't extract ICC information from file`);
|
||||
logger.warn(err);
|
||||
try {
|
||||
payload.metadata = await exifr.parse(buffer.content, {
|
||||
icc: true,
|
||||
iptc: true,
|
||||
ifd1: true,
|
||||
interop: true,
|
||||
translateValues: true,
|
||||
reviveValues: true,
|
||||
mergeOutput: false,
|
||||
});
|
||||
if (payload.metadata?.iptc?.Headline) {
|
||||
payload.title = payload.metadata.iptc.Headline;
|
||||
}
|
||||
}
|
||||
|
||||
if (meta.exif) {
|
||||
try {
|
||||
payload.metadata.exif = parseEXIF(meta.exif);
|
||||
} catch (err) {
|
||||
logger.warn(`Couldn't extract EXIF information from file`);
|
||||
logger.warn(err);
|
||||
if (!payload.description && payload.metadata?.iptc?.Caption) {
|
||||
payload.description = payload.metadata.iptc.Caption;
|
||||
}
|
||||
}
|
||||
|
||||
if (meta.iptc) {
|
||||
try {
|
||||
payload.metadata.iptc = parseIPTC(meta.iptc);
|
||||
payload.title = payload.metadata.iptc.headline || payload.title;
|
||||
payload.description = payload.description || payload.metadata.iptc.caption;
|
||||
payload.tags = payload.metadata.iptc.keywords;
|
||||
} catch (err) {
|
||||
logger.warn(`Couldn't extract IPTC information from file`);
|
||||
logger.warn(err);
|
||||
if (payload.metadata?.iptc?.Keywords) {
|
||||
payload.tags = payload.metadata.iptc.Keywords;
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn(`Couldn't extract metadata from file`);
|
||||
logger.warn(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
api/src/types/shims.d.ts
vendored
10
api/src/types/shims.d.ts
vendored
@@ -3,16 +3,6 @@ declare module 'grant' {
|
||||
export default grant;
|
||||
}
|
||||
|
||||
declare module 'icc' {
|
||||
const parse: (buf: Buffer) => Record<string, string>;
|
||||
export { parse };
|
||||
}
|
||||
|
||||
declare module 'exif-reader' {
|
||||
const exifReader: (buf: Buffer) => Record<string, any>;
|
||||
export default exifReader;
|
||||
}
|
||||
|
||||
declare module 'pino-http' {
|
||||
import PinoHttp from '@types/pino-http';
|
||||
const pinoHttp: PinoHttp;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
const IPTC_ENTRY_TYPES = new Map([
|
||||
[0x78, 'caption'],
|
||||
[0x6e, 'credit'],
|
||||
[0x19, 'keywords'],
|
||||
[0x37, 'dateCreated'],
|
||||
[0x50, 'byline'],
|
||||
[0x55, 'bylineTitle'],
|
||||
[0x7a, 'captionWriter'],
|
||||
[0x69, 'headline'],
|
||||
[0x74, 'copyright'],
|
||||
[0x0f, 'category'],
|
||||
]);
|
||||
|
||||
const IPTC_ENTRY_MARKER = Buffer.from([0x1c, 0x02]);
|
||||
|
||||
export default function parseIPTC(buffer: Buffer): Record<string, any> {
|
||||
if (!Buffer.isBuffer(buffer)) return {};
|
||||
|
||||
const iptc: Record<string, any> = {};
|
||||
let lastIptcEntryPos = buffer.indexOf(IPTC_ENTRY_MARKER);
|
||||
|
||||
while (lastIptcEntryPos !== -1) {
|
||||
lastIptcEntryPos = buffer.indexOf(IPTC_ENTRY_MARKER, lastIptcEntryPos + IPTC_ENTRY_MARKER.byteLength);
|
||||
|
||||
const iptcBlockTypePos = lastIptcEntryPos + IPTC_ENTRY_MARKER.byteLength;
|
||||
const iptcBlockSizePos = iptcBlockTypePos + 1;
|
||||
const iptcBlockDataPos = iptcBlockSizePos + 2;
|
||||
|
||||
const iptcBlockType = buffer.readUInt8(iptcBlockTypePos);
|
||||
const iptcBlockSize = buffer.readUInt16BE(iptcBlockSizePos);
|
||||
|
||||
if (!IPTC_ENTRY_TYPES.has(iptcBlockType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const iptcBlockTypeId = IPTC_ENTRY_TYPES.get(iptcBlockType);
|
||||
const iptcData = buffer.slice(iptcBlockDataPos, iptcBlockDataPos + iptcBlockSize).toString();
|
||||
|
||||
if (iptcBlockTypeId) {
|
||||
if (iptc[iptcBlockTypeId] == null) {
|
||||
iptc[iptcBlockTypeId] = iptcData;
|
||||
} else if (Array.isArray(iptc[iptcBlockTypeId])) {
|
||||
iptc[iptcBlockTypeId].push(iptcData);
|
||||
} else {
|
||||
iptc[iptcBlockTypeId] = [iptc[iptcBlockTypeId], iptcData];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iptc;
|
||||
}
|
||||
@@ -408,7 +408,7 @@ documentation: Documentation
|
||||
sidebar: Sidebar
|
||||
duration: Duration
|
||||
charset: Charset
|
||||
second: Second
|
||||
second: second
|
||||
file_moved: File Moved
|
||||
collection_created: Collection Created
|
||||
modified_on: Modified On
|
||||
|
||||
@@ -80,32 +80,41 @@
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<template v-if="file.metadata && file.metadata.exif && file.metadata.exif.exif && file.metadata.exif.image">
|
||||
<template
|
||||
v-if="
|
||||
file.metadata.ifd0?.Make ||
|
||||
file.metadata.ifd0?.Model ||
|
||||
file.metadata.exif?.FNumber ||
|
||||
file.metadata.exif?.ExposureTime ||
|
||||
file.metadata.exif?.FocalLength ||
|
||||
file.metadata.exif?.ISO
|
||||
"
|
||||
>
|
||||
<v-divider />
|
||||
|
||||
<div v-if="file.metadata.exif.image.Make && file.metadata.exif.image.Model">
|
||||
<div v-if="file.metadata.ifd0?.Make && file.metadata.ifd0?.Model">
|
||||
<dt>{{ t('camera') }}</dt>
|
||||
<dd>{{ file.metadata.exif.image.Make }} {{ file.metadata.exif.image.Model }}</dd>
|
||||
<dd>{{ file.metadata.ifd0.Make }} {{ file.metadata.ifd0.Model }}</dd>
|
||||
</div>
|
||||
|
||||
<div v-if="file.metadata.exif.exif.FNumber">
|
||||
<div v-if="file.metadata.exif?.FNumber">
|
||||
<dt>{{ t('exposure') }}</dt>
|
||||
<dd>ƒ/{{ file.metadata.exif.exif.FNumber }}</dd>
|
||||
<dd>ƒ/{{ file.metadata.exif.FNumber }}</dd>
|
||||
</div>
|
||||
|
||||
<div v-if="file.metadata.exif.exif.ExposureTime">
|
||||
<div v-if="file.metadata.exif?.ExposureTime">
|
||||
<dt>{{ t('shutter') }}</dt>
|
||||
<dd>1/{{ Math.round(1 / +file.metadata.exif.exif.ExposureTime) }} {{ t('second') }}</dd>
|
||||
<dd>1/{{ Math.round(1 / +file.metadata.exif.ExposureTime) }} {{ t('second') }}</dd>
|
||||
</div>
|
||||
|
||||
<div v-if="file.metadata.exif.exif.FocalLength">
|
||||
<div v-if="file.metadata.exif?.FocalLength">
|
||||
<dt>{{ t('focal_length') }}</dt>
|
||||
<dd>{{ file.metadata.exif.exif.FocalLength }}mm</dd>
|
||||
<dd>{{ file.metadata.exif.FocalLength }}mm</dd>
|
||||
</div>
|
||||
|
||||
<div v-if="file.metadata.exif.exif.ISO">
|
||||
<div v-if="file.metadata.exif?.ISO">
|
||||
<dt>{{ t('iso') }}</dt>
|
||||
<dd>{{ file.metadata.exif.exif.ISO }}</dd>
|
||||
<dd>{{ file.metadata.exif.ISO }}</dd>
|
||||
</div>
|
||||
</template>
|
||||
</dl>
|
||||
|
||||
87
changelog.md
87
changelog.md
@@ -7,51 +7,80 @@ _Changes marked with a :warning: contain potential breaking changes depending on
|
||||
### :sparkles: New Features
|
||||
|
||||
- **App**
|
||||
- [#7130](https://github.com/directus/directus/pull/7130) Add accordion group ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7101](https://github.com/directus/directus/pull/7101) Surface dropdown choices in advanced sidebar filter ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7130](https://github.com/directus/directus/pull/7130) Add accordion group
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7101](https://github.com/directus/directus/pull/7101) Surface dropdown choices in advanced sidebar filter
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
|
||||
### :rocket: Improvements
|
||||
|
||||
- **App**
|
||||
- [#7141](https://github.com/directus/directus/pull/7141) Title format repeater names ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7132](https://github.com/directus/directus/pull/7132) Add missing keys to translations ([@nickrum](https://github.com/nickrum))
|
||||
- [#7103](https://github.com/directus/directus/pull/7103) Add a standardized max-height to tree select interface ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7102](https://github.com/directus/directus/pull/7102) Render list group arrows on the left of the group checkbox in the tree select interface ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7059](https://github.com/directus/directus/pull/7059) Added "Default Open" Checkbox to Field Group Dividers ([@m0rtis0](https://github.com/m0rtis0))
|
||||
- [#7141](https://github.com/directus/directus/pull/7141) Title format repeater names
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7132](https://github.com/directus/directus/pull/7132) Add missing keys to translations
|
||||
([@nickrum](https://github.com/nickrum))
|
||||
- [#7103](https://github.com/directus/directus/pull/7103) Add a standardized max-height to tree select interface
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7102](https://github.com/directus/directus/pull/7102) Render list group arrows on the left of the group checkbox
|
||||
in the tree select interface ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7059](https://github.com/directus/directus/pull/7059) Added "Default Open" Checkbox to Field Group Dividers
|
||||
([@m0rtis0](https://github.com/m0rtis0))
|
||||
- **API**
|
||||
- [#7105](https://github.com/directus/directus/pull/7105) Stall login/pw reset to prevent email leaking ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#6580](https://github.com/directus/directus/pull/6580) Warn on Missing Migrations ([@jaycammarano](https://github.com/jaycammarano))
|
||||
- [#7105](https://github.com/directus/directus/pull/7105) Stall login/pw reset to prevent email leaking
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#6580](https://github.com/directus/directus/pull/6580) Warn on Missing Migrations
|
||||
([@jaycammarano](https://github.com/jaycammarano))
|
||||
|
||||
### :bug: Bug Fixes
|
||||
|
||||
- **App**
|
||||
- [#7142](https://github.com/directus/directus/pull/7142) Prevent duplicate alias fields from being created ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7135](https://github.com/directus/directus/pull/7135) Fix nested fields check in validate-payload handler ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7131](https://github.com/directus/directus/pull/7131) Fix default value of select-icon interface ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7142](https://github.com/directus/directus/pull/7142) Prevent duplicate alias fields from being created
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7135](https://github.com/directus/directus/pull/7135) Fix nested fields check in validate-payload handler
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7131](https://github.com/directus/directus/pull/7131) Fix default value of select-icon interface
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- **API**
|
||||
- [#7139](https://github.com/directus/directus/pull/7139) Fix cache-key generation for query params ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7104](https://github.com/directus/directus/pull/7104) Fix users accountability tracking ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7139](https://github.com/directus/directus/pull/7139) Fix cache-key generation for query params
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7104](https://github.com/directus/directus/pull/7104) Fix users accountability tracking
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
|
||||
### :memo: Documentation
|
||||
|
||||
- [#7106](https://github.com/directus/directus/pull/7106) Add note on conditional fields ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7099](https://github.com/directus/directus/pull/7099) Add note regarding required directus:extension field to extension docs ([@nickrum](https://github.com/nickrum))
|
||||
- [#7079](https://github.com/directus/directus/pull/7079) Add note on npm run dev restart ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7077](https://github.com/directus/directus/pull/7077) Add note on hook params ([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7106](https://github.com/directus/directus/pull/7106) Add note on conditional fields
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7099](https://github.com/directus/directus/pull/7099) Add note regarding required directus:extension field to
|
||||
extension docs ([@nickrum](https://github.com/nickrum))
|
||||
- [#7079](https://github.com/directus/directus/pull/7079) Add note on npm run dev restart
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
- [#7077](https://github.com/directus/directus/pull/7077) Add note on hook params
|
||||
([@rijkvanzanten](https://github.com/rijkvanzanten))
|
||||
|
||||
### :package: Dependency Updates
|
||||
|
||||
- [#7136](https://github.com/directus/directus/pull/7136) update typescript-eslint monorepo to v4.29.0 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7117](https://github.com/directus/directus/pull/7117) update dependency joi to v17.4.2 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7115](https://github.com/directus/directus/pull/7115) update dependency knex to v0.95.9 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7110](https://github.com/directus/directus/pull/7110) update dependency sass to v1.37.0 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7109](https://github.com/directus/directus/pull/7109) update dependency eslint to v7.32.0 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7094](https://github.com/directus/directus/pull/7094) update dependency @rollup/plugin-commonjs to v20 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7093](https://github.com/directus/directus/pull/7093) update dependency chalk to v4.1.2 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7090](https://github.com/directus/directus/pull/7090) update dependency npm-watch to v0.11.0 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7089](https://github.com/directus/directus/pull/7089) update dependency eslint-plugin-vue to v7.15.0 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7087](https://github.com/directus/directus/pull/7087) update styfle/cancel-workflow-action action to v0.9.1 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7085](https://github.com/directus/directus/pull/7085) update dependency rollup to v2.55.1 ([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7136](https://github.com/directus/directus/pull/7136) update typescript-eslint monorepo to v4.29.0
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7117](https://github.com/directus/directus/pull/7117) update dependency joi to v17.4.2
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7115](https://github.com/directus/directus/pull/7115) update dependency knex to v0.95.9
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7110](https://github.com/directus/directus/pull/7110) update dependency sass to v1.37.0
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7109](https://github.com/directus/directus/pull/7109) update dependency eslint to v7.32.0
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7094](https://github.com/directus/directus/pull/7094) update dependency @rollup/plugin-commonjs to v20
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7093](https://github.com/directus/directus/pull/7093) update dependency chalk to v4.1.2
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7090](https://github.com/directus/directus/pull/7090) update dependency npm-watch to v0.11.0
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7089](https://github.com/directus/directus/pull/7089) update dependency eslint-plugin-vue to v7.15.0
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7087](https://github.com/directus/directus/pull/7087) update styfle/cancel-workflow-action action to v0.9.1
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
- [#7085](https://github.com/directus/directus/pull/7085) update dependency rollup to v2.55.1
|
||||
([@renovate[bot]](https://github.com/apps/renovate))
|
||||
|
||||
## v9.0.0-rc.87 (July 28, 2021)
|
||||
|
||||
|
||||
35
package-lock.json
generated
35
package-lock.json
generated
@@ -90,14 +90,13 @@
|
||||
"dotenv": "^10.0.0",
|
||||
"eventemitter2": "^6.4.3",
|
||||
"execa": "^5.1.1",
|
||||
"exif-reader": "^1.0.3",
|
||||
"exifr": "^7.1.2",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.17.2",
|
||||
"fs-extra": "^10.0.0",
|
||||
"grant": "^5.4.14",
|
||||
"graphql": "^15.5.0",
|
||||
"graphql-compose": "^9.0.1",
|
||||
"icc": "^2.0.0",
|
||||
"inquirer": "^8.1.1",
|
||||
"joi": "^17.3.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
@@ -19872,10 +19871,10 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/exif-reader": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/exif-reader/-/exif-reader-1.0.3.tgz",
|
||||
"integrity": "sha512-tWMBj1+9jUSibgR/kv/GQ/fkR0biaN9GEZ5iPdf7jFeH//d2bSzgPoaWf1OfMv4MXFD4upwvpCCyeMvSyLWSfA=="
|
||||
"node_modules/exifr": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.2.tgz",
|
||||
"integrity": "sha512-XZRvQJFJVeMfb6BLY755MoOBq+V644nzxRPjZ8G5+qvBi0nfcT1n2OdA4CshBKTF12fC1RQM9cpiKtQ/LwFLog=="
|
||||
},
|
||||
"node_modules/exit": {
|
||||
"version": "0.1.2",
|
||||
@@ -26541,14 +26540,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/icc": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/icc/-/icc-2.0.0.tgz",
|
||||
"integrity": "sha512-VSTak7UAcZu1E24YFvcoHVpVg/ZUVyb0G1v0wUIibfz5mHvcFeI/Gpn8C0cAUKw5jCCGx5JBcV4gULu6hX97mA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
@@ -75477,14 +75468,13 @@
|
||||
"dotenv": "^10.0.0",
|
||||
"eventemitter2": "^6.4.3",
|
||||
"execa": "^5.1.1",
|
||||
"exif-reader": "^1.0.3",
|
||||
"exifr": "^7.1.2",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.17.2",
|
||||
"fs-extra": "^10.0.0",
|
||||
"grant": "^5.4.14",
|
||||
"graphql": "^15.5.0",
|
||||
"graphql-compose": "^9.0.1",
|
||||
"icc": "^2.0.0",
|
||||
"inquirer": "^8.1.1",
|
||||
"ioredis": "^4.27.6",
|
||||
"joi": "^17.3.0",
|
||||
@@ -76951,10 +76941,10 @@
|
||||
"clone-regexp": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"exif-reader": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/exif-reader/-/exif-reader-1.0.3.tgz",
|
||||
"integrity": "sha512-tWMBj1+9jUSibgR/kv/GQ/fkR0biaN9GEZ5iPdf7jFeH//d2bSzgPoaWf1OfMv4MXFD4upwvpCCyeMvSyLWSfA=="
|
||||
"exifr": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.2.tgz",
|
||||
"integrity": "sha512-XZRvQJFJVeMfb6BLY755MoOBq+V644nzxRPjZ8G5+qvBi0nfcT1n2OdA4CshBKTF12fC1RQM9cpiKtQ/LwFLog=="
|
||||
},
|
||||
"exit": {
|
||||
"version": "0.1.2",
|
||||
@@ -82233,11 +82223,6 @@
|
||||
"resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz",
|
||||
"integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ=="
|
||||
},
|
||||
"icc": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/icc/-/icc-2.0.0.tgz",
|
||||
"integrity": "sha512-VSTak7UAcZu1E24YFvcoHVpVg/ZUVyb0G1v0wUIibfz5mHvcFeI/Gpn8C0cAUKw5jCCGx5JBcV4gULu6hX97mA=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
|
||||
Reference in New Issue
Block a user