Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite of Image and Files (breaking) #7070

Merged
merged 105 commits into from
May 26, 2022
Merged
Show file tree
Hide file tree
Changes from 91 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
1ef5823
First pass at s3AssetsAPI, now to wire up
rohan-deshpande Dec 9, 2021
b51ff6c
Implemented asset mode switch in createImagesContext
rohan-deshpande Dec 9, 2021
e9e861e
Implemented asset mode switch in createFilesContext
rohan-deshpande Dec 10, 2021
751a5c0
Renamed function
rohan-deshpande Dec 10, 2021
a784bf4
Fixed bugs caused by trying to send a stream to S3, now sending buffe…
rohan-deshpande Dec 10, 2021
ad9770f
Update packages/keystone/src/lib/context/createImagesContext.ts
rohan-deshpande Dec 15, 2021
8614b79
Tidy up
emmatown Feb 2, 2022
6645952
Stream file upload
emmatown Feb 3, 2022
f6eefc1
Fix urls
emmatown Feb 3, 2022
9659ba7
Init s3 at startup rather than per request
emmatown Feb 3, 2022
7fa5f5a
Move things
emmatown Feb 3, 2022
d19e6b9
Remove a duplicated thing
emmatown Feb 3, 2022
164754a
Tests
emmatown Feb 3, 2022
1ce623f
Update schemas
emmatown Feb 3, 2022
2b36aa1
Update CI config
emmatown Feb 3, 2022
bdd5a5a
Change bucket name
emmatown Feb 3, 2022
ffca2c4
Make test bucket publicly readable
emmatown Feb 3, 2022
81aef3d
Fix CI config
emmatown Feb 3, 2022
b2c6a3a
Prettier
emmatown Feb 3, 2022
24bc325
Apply suggestions from code review
emmatown Feb 3, 2022
630219f
Update other postgres user and password
emmatown Feb 3, 2022
90bb8de
Get image size if it's not stored in the metadata
emmatown Feb 3, 2022
5cfd961
Add test for uploading an image directly to s3 and adding it to a fie…
emmatown Feb 4, 2022
84d16bd
Docs and changeset
emmatown Feb 4, 2022
6c61416
comparable functionality
Noviny Mar 15, 2022
6c0c60d
small examples schema update
Noviny Mar 22, 2022
b327231
Add removeOnDelete option
Noviny Mar 22, 2022
4f43460
update yarn.lock
dcousens Mar 23, 2022
b1e37ea
remove fast-glob duplicate from devDependencies
dcousens Mar 23, 2022
51132eb
bump dotenv
dcousens Mar 23, 2022
85e32dc
small updates
Noviny Mar 23, 2022
818d162
adding/updating tests
Noviny Mar 29, 2022
188e1b9
use return, not break, fix broken S3 file deletion
dcousens Apr 13, 2022
8822304
work in progress changes
Noviny May 4, 2022
24035fd
Fix things
emmatown May 9, 2022
9184b66
WIP path prefix
emmatown May 10, 2022
51c7921
Fix a thing
emmatown May 10, 2022
5a708f3
continue, not break
emmatown May 10, 2022
cb7b456
Fix preserve
emmatown May 10, 2022
fbe62f8
Test fixes 1
Noviny May 16, 2022
a2c89a2
tests updates 2
Noviny May 16, 2022
bad76b8
test fixes 3
Noviny May 16, 2022
f1958e0
remove problematic import
Noviny May 16, 2022
4082ba1
yarn updates
Noviny May 16, 2022
17ad29c
typescript fixes
Noviny May 16, 2022
f13a3c4
fix ordering
Noviny May 16, 2022
00b158b
Revert error message change
emmatown May 16, 2022
231152c
Merge branch 's3-assets' of https://github.com/keystonejs/keystone in…
emmatown May 16, 2022
088999a
store test files in temp dir
Noviny May 16, 2022
6434d2c
Run deletions at source before operation
emmatown May 16, 2022
3adf3e2
Fix local file serving and basic example
emmatown May 16, 2022
fc14fea
base documentation updates
Noviny May 16, 2022
1551648
Fix s3 proxy things
emmatown May 17, 2022
e46bb0f
Delete CHANGELOG.md
Noviny May 17, 2022
d9b6d8c
Use my_ to disambiguate naming formality
dcousens May 17, 2022
b52572d
Config updates
emmatown May 17, 2022
2cbfc23
Use my_ for examples
dcousens May 17, 2022
1419859
Small docs fix
Noviny May 17, 2022
84a9cbf
update changelog to be more reflective of actual changes
Noviny May 17, 2022
f293d2b
rename addServerRoute to serverRoute
Noviny May 17, 2022
0be9188
drop superfluous .assets object
dcousens May 17, 2022
58b86ff
rephrase unknown storage key error
dcousens May 17, 2022
e1c9cdd
updates to storage config
May 17, 2022
986673e
Update S3 example
emmatown May 17, 2022
8e98571
Merge branch 's3-assets' of https://github.com/keystonejs/keystone in…
emmatown May 17, 2022
f4ca913
S3 Assets example update
emmatown May 17, 2022
3d82d85
remove unused ref code
Noviny May 17, 2022
36989cc
Add JSDoc comments to StorageConfig types
Noviny May 17, 2022
92f8183
change word
Noviny May 17, 2022
787363f
Fix URLs
emmatown May 17, 2022
ba0d02a
Merge branch 's3-assets' of https://github.com/keystonejs/keystone in…
emmatown May 17, 2022
0361030
Update packages/core/package.json
Noviny May 17, 2022
d97e8db
update images ui
gwyneplaine May 17, 2022
7e68a9b
Merge branch 's3-assets' of https://github.com/keystonejs/keystone in…
gwyneplaine May 17, 2022
e1ab859
add target _blank to image anchor
gwyneplaine May 17, 2022
1ad5b1b
UI updates
emmatown May 17, 2022
32f725d
internal rename for consistency
Noviny May 18, 2022
03813b1
UI updates
emmatown May 18, 2022
d0bf608
add transformName for both files and images
Noviny May 18, 2022
34f115c
docs update
Noviny May 18, 2022
d4531d0
rename generatedUrl to generateUrl
Noviny May 18, 2022
f43e358
Shorten config example
May 19, 2022
e5968d2
update generateUrl
May 19, 2022
c003c0d
small fixes
Noviny May 23, 2022
9f13405
change files on S3 to octet streams
dcousens May 23, 2022
7433de8
remove redundant null check
dcousens May 23, 2022
795c3fc
Update default generateName for files
emmatown May 23, 2022
d3ef9fc
remove redundant error checking
dcousens May 23, 2022
424ded7
Apply suggestions from code review
dcousens May 23, 2022
1131262
move endpoint string manipulation out of request
dcousens May 23, 2022
4f56f3f
yarn format
dcousens May 23, 2022
ac974bd
Update local s3 serving
emmatown May 23, 2022
85e8b7f
Remove s3 proxy
emmatown May 23, 2022
68b2909
changes inline documentation copy
dcousens May 23, 2022
67a638a
Await deletions
emmatown May 23, 2022
a2c2f95
fix images to store the data
Noviny May 23, 2022
b056dfd
change warning copy
dcousens May 23, 2022
7463cb8
update yarn.lock
dcousens May 23, 2022
219ceda
yarn format
dcousens May 23, 2022
e5a90b7
does this work?
Noviny May 23, 2022
e646202
Delete utils.ts
emmatown May 23, 2022
925e461
Update .changeset/unlucky-ducks-raise.md
Noviny May 25, 2022
9819c22
Update .changeset/unlucky-ducks-raise.md
Noviny May 25, 2022
570d6ca
update changeset
Noviny May 26, 2022
a62ea01
Update changeset
emmatown May 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions .changeset/unlucky-ducks-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
'@keystone-6/core': major
---
#### Breaking

##### Move of `image` and `files` in the keystone config into new option `storage`

The `image` and `files` config options have been removed from Keystone's config - the configuration has
been moved into a new `storage` configuration object.

Old:

```ts
export default config({
image: { upload: 's3' },
lists: {
images: { fields: { image() }
/* ... */
},
/* ... */
})
```

New:

```ts
export default config({
storage: {
my_image_storage: {
kind: 's3',
type: 'image',
bucketName: S3_BUCKET_NAME,
region: S3_REGION,
accessKeyId: S3_ACCESS_KEY_ID,
secretAccessKey: S3_SECRET_ACCESS_KEY
},
}
lists: {
images: { fields: image({ storage: 'my_image_storage' }) }
/* ... */
},
/* ... */
})
```

##### Removal of refs for `images` and `files`

Refs were an interesting situation! They allowed you to link images stored in your storage source (s3 or local), and use the same
image anywhere else images are used. This causes a bunch of complication, and prevented Keystone ever reliably being able
to remove images from your source, as it couldn't easily track where images were used.

To simplify things for you and us, we're removing `refs` as a concept, but don't panic just yet, we are conceptually replacing
them with something you are already familiar with: `relationships`.

If you wanted refs, where images could be available in multiple places, our new recommendation is:

```ts
export default config({
storage: {
my_image_storage: {
/* ... */
},
}
lists: {
images: { fields: { image({ storage: 'my_image_storage' }) } },
Noviny marked this conversation as resolved.
Show resolved Hide resolved
user: { fields: avatar: relationship({ ref: 'images' })}
blog: { fields: photos: relationship({ ref: 'images', many: true })}
/* ... */
},
/* ... */
})
```

This allows mirroring of the old functionality, while allowing us to add the below feature/breaking change.

##### Images and Files will now be deleted when deleted

Before this change, if you uploaded a file or image, Keystone would never remove it from where it was stored. The inability to tidy up unused
files or images was unwelcome. With the removal of `ref`, we can no remove things from the source, and this will be done by default.
Noviny marked this conversation as resolved.
Show resolved Hide resolved

If you don't want files or images removed, we recommend storing them as a `relationship`, rather than on items themselves, so the files
or images persist separate to lists that use them.

If you want the existing behaviour of keystone, set `preserve: true` on the storage instead.

##### `file` and `image` URLs now use `generateUrl`, allowing more control over what is returned to the user

##### Local images no longer need a baseUrl

Previously, if you were using local storage (you scallywag), you needed to provide a path for keystone to host images on. You
can still do this, but if you plan on serving them from another location, you can opt into not doing this.


```ts
{
- baseUrl: '/images'
+ serverRoute: {
+ path: '/images'
+ }
}
```

#### New bits

S3 support is no longer 'experimental'
S3 supports proxying through the keystone server
S3 signing is now supported
`preserve` flag added to both `file` and `image` fields to allow removal of files from the source
Support for multiple `storage` sources - each `image` and `file` field can now use its own config (or not)

#### Changes


91 changes: 87 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ jobs:
postgres:
image: postgres:12
env:
POSTGRES_USER: keystone5
POSTGRES_PASSWORD: k3yst0n3
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
POSTGRES_DB: test_db
ports:
- 5432:5432
Expand Down Expand Up @@ -80,15 +80,15 @@ jobs:

- name: Unit tests
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
run: yarn jest --ci --runInBand api-tests
run: yarn jest --ci --runInBand api-tests --testPathIgnorePatterns=examples-smoke-tests --testPathIgnorePatterns=tests/api-tests/fields/crud
env:
CLOUDINARY_CLOUD_NAME: ${{ secrets.CLOUDINARY_CLOUD_NAME }}
CLOUDINARY_KEY: ${{ secrets.CLOUDINARY_KEY }}
CLOUDINARY_SECRET: ${{ secrets.CLOUDINARY_SECRET }}
CI_NODE_TOTAL: 9
CI_NODE_INDEX: ${{ matrix.index }}
TEST_ADAPTER: ${{ matrix.adapter }}
DATABASE_URL: ${{ matrix.adapter == 'sqlite' && 'file:./dev.db' || 'postgres://keystone5:k3yst0n3@localhost:5432/test_db' }}
DATABASE_URL: ${{ matrix.adapter == 'sqlite' && 'file:./dev.db' || 'postgres://testuser:testpass@localhost:5432/test_db' }}

unit_tests:
name: Package Unit Tests
Expand Down Expand Up @@ -129,6 +129,89 @@ jobs:
CLOUDINARY_KEY: ${{ secrets.CLOUDINARY_KEY }}
CLOUDINARY_SECRET: ${{ secrets.CLOUDINARY_SECRET }}

field_crud_tests:
name: Field CRUD Tests
needs: should_run_tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:12
env:
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
POSTGRES_DB: test_db
ports:
- 5432:5432
strategy:
fail-fast: false
matrix:
adapter: ['postgresql', 'sqlite']
steps:
- name: Checkout Repo
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
uses: actions/checkout@v2

- name: Setup Node.js LTS
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
uses: actions/setup-node@main
with:
node-version: lts/*

- name: Get yarn cache directory path
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v2
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
id: yarn-cache
with:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
node_modules
key: ${{ runner.os }}-yarn-v5-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-v5-

- name: Install Dependencies
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
run: yarn
- name: Setup local S3 bucket
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
run: |
docker run -d -p 9000:9000 --name minio \
-e "MINIO_ACCESS_KEY=keystone" \
-e "MINIO_SECRET_KEY=keystone" \
-v /tmp/data:/data \
-v /tmp/config:/root/.minio \
minio/minio server /data

export AWS_ACCESS_KEY_ID=keystone
export AWS_SECRET_ACCESS_KEY=keystone
export AWS_EC2_METADATA_DISABLED=true



aws --endpoint-url http://127.0.0.1:9000/ s3 mb s3://keystone-test
aws --endpoint-url http://127.0.0.1:9000/ s3api put-bucket-policy --bucket keystone-test --policy file://tests/api-tests/s3-public-read-policy.json

- name: Unit tests
if: needs.should_run_tests.outputs.shouldRunTests == 'true'
run: yarn jest --ci --runInBand tests/api-tests/fields/crud
env:
CLOUDINARY_CLOUD_NAME: ${{ secrets.CLOUDINARY_CLOUD_NAME }}
CLOUDINARY_KEY: ${{ secrets.CLOUDINARY_KEY }}
CLOUDINARY_SECRET: ${{ secrets.CLOUDINARY_SECRET }}
S3_ENDPOINT: http://127.0.0.1:9000/
S3_FORCE_PATH_STYLE: true
S3_BUCKET_NAME: keystone-test
S3_ACCESS_KEY_ID: keystone
S3_SECRET_ACCESS_KEY: keystone
# this doesn't mean anything when we're using a custom s3 endpoint but the sdk wants something so we just give it something
S3_REGION: us-east-1
TEST_ADAPTER: ${{ matrix.adapter }}
DATABASE_URL: ${{ matrix.adapter == 'sqlite' && 'file:./dev.db' || 'postgres://testuser:testpass@localhost:5432/test_db' }}

examples_tests:
name: Testing example project
needs: should_run_tests
Expand Down
Loading