generated from 8iq/nodejs-hackathon-boilerplate-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(keystone): DOMA-10804 field refactoring
- Loading branch information
1 parent
e5b2f1c
commit 1f08a15
Showing
11 changed files
with
174 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 3 additions & 2 deletions
5
...ystone/fields/LargeText/Implementation.js → ...fields/CloudStorageText/Implementation.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,15 @@ | ||
const { Text } = require('@keystonejs/fields') | ||
|
||
class LargeTextImplementation extends Text.implementation { | ||
class CloudStorageTextImplementation extends Text.implementation { | ||
constructor (path, { | ||
adapter, | ||
}) { | ||
super(...arguments) | ||
this.fileAdapter = adapter | ||
this.isMultiline = true | ||
} | ||
} | ||
|
||
module.exports = { | ||
LargeTextImplementation, | ||
CloudStorageTextImplementation, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# CloudStorageText | ||
|
||
The `CloudStorageText` field simplifies the storage of large text data by abstracting the implementation of cloud storage usage. | ||
|
||
## Basic Usage | ||
|
||
Simply add the `CloudStorageText` field type and a file adapter, and your text data will be stored in cloud storage. This helps avoid storing large datasets directly in the database. You can use it just like a common `Text` field in your code. | ||
|
||
```js | ||
const fileAdapter = new FileAdapter('LOG_FILE_NAME') | ||
|
||
keystone.createList('Log', { | ||
fields: { | ||
xmlLog: { | ||
type: 'CloudStorageText', | ||
adapter: fileAdapter, | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
# GraphQL | ||
|
||
The `CloudStorageText` field behaves like a standard string (`Text` field). During create/update operations, the input value is saved to cloud storage, and only a reference to the saved file is stored in the database. For read operations, the saved file is downloaded from cloud storage, and its contents are provided as a string. | ||
|
||
# Storage | ||
|
||
The text value is stored as a file in the cloud, while the database only holds a reference (link) to the source file. | ||
|
||
# Configuration | ||
|
||
You will need to configure a file adapter to work with cloud storage. Example: | ||
|
||
```js | ||
const fileAdapter = new FileAdapter('LOG_FILE_NAME') | ||
``` | ||
|
||
or | ||
|
||
```js | ||
const fileAdapter = new FileAdapter('LOG_FILE_NAME', false, false, { bucket: 'BUCKET_FOR_LOGS'}) | ||
``` | ||
|
||
Ensure your cloud storage configuration is properly set up and accessible for file storage. | ||
|
||
# Notes | ||
|
||
- The `CloudStorageText` field is ideal for storing large logs, parsed values, or other text data that may exceed the typical size limits of database fields. | ||
- The text is stored as a file in cloud storage, reducing the load on the database while still providing easy access to the data. |
84 changes: 84 additions & 0 deletions
84
packages/keystone/fields/CloudStorageText/adapters/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
const { Text } = require('@keystonejs/fields') | ||
const cuid = require('cuid') | ||
const isNil = require('lodash/isNil') | ||
|
||
const { bufferToStream, readFileFromStream, getObjectStream } = require('@open-condo/keystone/file') | ||
|
||
const CommonInterface = superclass => class extends superclass { | ||
|
||
constructor () { | ||
super(...arguments) | ||
if (!this.config.adapter) { | ||
throw new Error('CloudStorageText field cannot be used without a file adapter') | ||
} | ||
this.fileAdapter = this.config.adapter | ||
} | ||
|
||
setupHooks ({ addPreSaveHook, addPostReadHook }) { | ||
addPreSaveHook(async (item) => { | ||
if (this._isFieldDefined(item)) { | ||
item[this.path] = await this._saveFileToAdapter(item[this.path]) | ||
} | ||
return item | ||
}) | ||
|
||
addPostReadHook(async (item) => { | ||
if (item[this.path]) { | ||
item[this.path] = await this._readFileFromAdapter(item[this.path]) | ||
} | ||
return item | ||
}) | ||
} | ||
|
||
_isFieldDefined (item) { | ||
return item && !isNil(item[this.path]) | ||
} | ||
|
||
async _saveFileToAdapter (content) { | ||
const stream = bufferToStream(content) | ||
const originalFilename = this._generateFilename() | ||
const mimetype = 'text/plain' | ||
const encoding = 'utf8' | ||
|
||
const { id, filename, _meta } = await this.fileAdapter.save({ | ||
stream, | ||
filename: originalFilename, | ||
mimetype, | ||
encoding, | ||
id: cuid(), | ||
}) | ||
|
||
return { | ||
id, | ||
filename, | ||
originalFilename, | ||
mimetype, | ||
encoding, | ||
_meta, | ||
} | ||
} | ||
|
||
async _readFileFromAdapter (fileMetadata) { | ||
const fileStream = await getObjectStream(fileMetadata, this.fileAdapter) | ||
const fileContent = await readFileFromStream(fileStream) | ||
return fileContent.toString() | ||
} | ||
|
||
_generateFilename () { | ||
return `${new Date().toISOString()}` | ||
} | ||
|
||
addToTableSchema (table) { | ||
table.jsonb(this.path) | ||
} | ||
} | ||
|
||
class CloudStorageTextKnexFieldAdapter extends CommonInterface(Text.adapters.knex) {} | ||
class CloudStorageTextMongooseFieldAdapter extends CommonInterface(Text.adapters.mongoose) {} | ||
class CloudStorageTextPrismaFieldAdapter extends CommonInterface(Text.adapters.prisma) {} | ||
|
||
module.exports = { | ||
mongoose: CloudStorageTextKnexFieldAdapter, | ||
knex: CloudStorageTextMongooseFieldAdapter, | ||
prisma: CloudStorageTextPrismaFieldAdapter, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
const { Text } = require('@keystonejs/fields') | ||
|
||
const CloudStorageTextAdapters = require('./adapters') | ||
const { CloudStorageTextImplementation } = require('./Implementation') | ||
|
||
module.exports = { | ||
type: 'CloudStorageText', | ||
implementation: CloudStorageTextImplementation, | ||
views: { | ||
...Text.views, | ||
Controller: require.resolve('./views/Controller'), | ||
}, | ||
adapters: CloudStorageTextAdapters, | ||
} |
2 changes: 1 addition & 1 deletion
2
...tone/fields/LargeText/views/Controller.js → ...elds/CloudStorageText/views/Controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import FieldController from '@keystonejs/fields/Controller' | ||
|
||
export default class LargeTextController extends FieldController { | ||
export default class CloudStorageTextController extends FieldController { | ||
getFilterTypes = () => [] | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters