Allow specifying path to schema-sync folder with SCHEMA_SYNC_PATH#72
Allow specifying path to schema-sync folder with SCHEMA_SYNC_PATH#72julbd wants to merge 5 commits intobcc-code:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds support for customizing the path to the schema-sync folder via the SCHEMA_SYNC_PATH environment variable. By default, it continues to use (Directus root)/schema-sync.
Changes:
- Introduced
SCHEMA_SYNC_PATHenvironment variable to allow customization of the schema-sync folder location - Refactored
ExportHelperstatic class into instance-basedExportMetaclass to support configurable paths - Updated all components (
SchemaExporter,CollectionExporter,ExportManager) to accept and use the configurable path
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/exportMeta.ts | New file containing the ExportMeta class with path configuration support, moved from ExportHelper in utils.ts |
| src/utils.ts | Removed ExportHelper class, extracted fileExists as a standalone utility function |
| src/types.ts | Added optional path parameter to CollectionExporterOptions |
| src/index.ts | Updated to instantiate ExportMeta with SCHEMA_SYNC_PATH and pass path to all exporters |
| src/exportManager.ts | Added path parameter to constructor and passes it to collection exporters |
| src/schemaExporter.ts | Added path option to constructor and uses ExportMeta for directory resolution |
| src/collectionExporter.ts | Updated to use ExportMeta with configurable path instead of static ExportHelper |
| src/updateManager.ts | Removed unused ExportHelper import |
| README.md | Added documentation for SCHEMA_SYNC_PATH environment variable and cleaned up trailing whitespace |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/exportMeta.ts
Outdated
| public schemaDir: string; | ||
|
|
||
| constructor(schemaDir?: string) { | ||
| this.schemaDir = resolve(process.cwd(), schemaDir ?? 'schema-sync') | ||
| } | ||
|
|
||
| get dataDir() { | ||
| return resolve(this.schemaDir, 'data'); | ||
| } | ||
|
|
||
| get hashFile() { | ||
| return resolve(this.schemaDir, 'hash.txt'); | ||
| } | ||
|
|
||
| async updateExportMeta() { | ||
| const hasher = createHash('sha256'); | ||
| const files = await readdir(this.dataDir); | ||
| for (const file of files) { | ||
| if (file.endsWith('.json')) { | ||
| const json = await readFile(`${this.dataDir}/${file}`, { encoding: 'utf8' }); | ||
| hasher.update(json); | ||
| } | ||
| } | ||
| const hash = hasher.digest('hex'); | ||
|
|
||
| const { hash: previousHash } = await this.getExportMeta() || {}; | ||
|
|
||
| // Only update hash file if it has changed | ||
| if (hash === previousHash) return false; | ||
|
|
||
| const ts = utcTS(); | ||
| const txt = hash + '@' + ts; | ||
|
|
||
| await writeFile(this.hashFile, txt); | ||
| return { | ||
| hash, | ||
| ts, | ||
| }; | ||
| } | ||
|
|
||
| async getExportMeta() { | ||
| try { | ||
| const content = await readFile(this.hashFile, { encoding: 'utf8' }); | ||
| const [hash, ts] = content.split('@'); | ||
|
|
||
| if (hash && ts && new Date(ts).toString() !== 'Invalid Date') { | ||
| return { | ||
| hash, | ||
| ts, | ||
| }; | ||
| } | ||
| } catch { | ||
| // ignore | ||
| } | ||
| return null; | ||
| } |
There was a problem hiding this comment.
Inconsistent indentation detected. The code uses spaces instead of tabs. The entire class body (lines 20-61) should use tabs for indentation to match the project's style.
| public schemaDir: string; | |
| constructor(schemaDir?: string) { | |
| this.schemaDir = resolve(process.cwd(), schemaDir ?? 'schema-sync') | |
| } | |
| get dataDir() { | |
| return resolve(this.schemaDir, 'data'); | |
| } | |
| get hashFile() { | |
| return resolve(this.schemaDir, 'hash.txt'); | |
| } | |
| async updateExportMeta() { | |
| const hasher = createHash('sha256'); | |
| const files = await readdir(this.dataDir); | |
| for (const file of files) { | |
| if (file.endsWith('.json')) { | |
| const json = await readFile(`${this.dataDir}/${file}`, { encoding: 'utf8' }); | |
| hasher.update(json); | |
| } | |
| } | |
| const hash = hasher.digest('hex'); | |
| const { hash: previousHash } = await this.getExportMeta() || {}; | |
| // Only update hash file if it has changed | |
| if (hash === previousHash) return false; | |
| const ts = utcTS(); | |
| const txt = hash + '@' + ts; | |
| await writeFile(this.hashFile, txt); | |
| return { | |
| hash, | |
| ts, | |
| }; | |
| } | |
| async getExportMeta() { | |
| try { | |
| const content = await readFile(this.hashFile, { encoding: 'utf8' }); | |
| const [hash, ts] = content.split('@'); | |
| if (hash && ts && new Date(ts).toString() !== 'Invalid Date') { | |
| return { | |
| hash, | |
| ts, | |
| }; | |
| } | |
| } catch { | |
| // ignore | |
| } | |
| return null; | |
| } | |
| public schemaDir: string; | |
| constructor(schemaDir?: string) { | |
| this.schemaDir = resolve(process.cwd(), schemaDir ?? 'schema-sync') | |
| } | |
| get dataDir() { | |
| return resolve(this.schemaDir, 'data'); | |
| } | |
| get hashFile() { | |
| return resolve(this.schemaDir, 'hash.txt'); | |
| } | |
| async updateExportMeta() { | |
| const hasher = createHash('sha256'); | |
| const files = await readdir(this.dataDir); | |
| for (const file of files) { | |
| if (file.endsWith('.json')) { | |
| const json = await readFile(`${this.dataDir}/${file}`, { encoding: 'utf8' }); | |
| hasher.update(json); | |
| } | |
| } | |
| const hash = hasher.digest('hex'); | |
| const { hash: previousHash } = await this.getExportMeta() || {}; | |
| // Only update hash file if it has changed | |
| if (hash === previousHash) return false; | |
| const ts = utcTS(); | |
| const txt = hash + '@' + ts; | |
| await writeFile(this.hashFile, txt); | |
| return { | |
| hash, | |
| ts, | |
| }; | |
| } | |
| async getExportMeta() { | |
| try { | |
| const content = await readFile(this.hashFile, { encoding: 'utf8' }); | |
| const [hash, ts] = content.split('@'); | |
| if (hash && ts && new Date(ts).toString() !== 'Invalid Date') { | |
| return { | |
| hash, | |
| ts, | |
| }; | |
| } | |
| } catch { | |
| // ignore | |
| } | |
| return null; | |
| } |
|
|
||
|
|
||
| export function utcTS(isoTimestamp: string = new Date().toISOString()) { | ||
| return isoTimestamp.replace('T', ' ').replace(/\.\d*Z/, ''); |
There was a problem hiding this comment.
Inconsistent indentation detected. The function uses spaces instead of tabs. Line 66 should use tabs for indentation to match the project's style.
| return isoTimestamp.replace('T', ' ').replace(/\.\d*Z/, ''); | |
| return isoTimestamp.replace('T', ' ').replace(/\.\d*Z/, ''); |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Add
SCHEMA_SYNC_PATHenvironment variable allowing to specify/customize the path toschema-sync. By default :(Directus root)/schema-syncNote : Initially, I planned to add a global cli option
--path, but the current implementation with both global and command-scoped variables required too much refactoring.