forked from maltejur/directus-extension-generate-types
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(synced-files): allows automatic save of a .d.ts file storing typ…
…es on creat/update/delete of collections, fields or relations Add a hook saving types in files List files to save to in an environment va factorize data gathering between the admin module and the hook closed maltejur#27
- Loading branch information
Showing
13 changed files
with
174 additions
and
62 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
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,59 +1,27 @@ | ||
import type { Collections, Field } from "lib/types"; | ||
import type { Field } from "../../lib/types"; | ||
import { | ||
Collection as DirectusCollection, | ||
Relation, | ||
} from "@directus/shared/types"; | ||
import type { AxiosResponse } from "axios"; | ||
import { warn } from "./console"; | ||
import { gatherCollectionsData } from "../../lib/generate-types/utils"; | ||
|
||
export async function getCollections(api) { | ||
const collectionsRes: AxiosResponse<{ data: DirectusCollection[] }> = | ||
await api.get("/collections?limit=-1"); | ||
const rawCollections = collectionsRes.data.data; | ||
const collections: Collections = {}; | ||
rawCollections | ||
.sort((a, b) => a.collection.localeCompare(b.collection)) | ||
.forEach( | ||
(collection) => | ||
(collections[collection.collection] = { ...collection, fields: [] }) | ||
); | ||
const fieldsRes: AxiosResponse<{ data: Field[] }> = await api.get( | ||
const collectionsResponse: AxiosResponse<{ data: DirectusCollection[] }> | ||
= await api.get("/collections?limit=-1"); | ||
|
||
const fieldsResponse: AxiosResponse<{ data: Field[] }> = await api.get( | ||
"/fields?limit=-1" | ||
); | ||
const fields = fieldsRes.data.data; | ||
fields | ||
.sort((a, b) => a.field.localeCompare(b.field)) | ||
.forEach((field) => { | ||
if (!collections[field.collection]) { | ||
warn(`${field.collection} not found`); | ||
return; | ||
} | ||
collections[field.collection].fields.push(field); | ||
}); | ||
Object.keys(collections).forEach((key) => { | ||
if (collections[key].fields.length === 0) delete collections[key]; | ||
}); | ||
const relationsRes: AxiosResponse<{ data: Relation[] }> = await api.get( | ||
|
||
const relationsResponse: AxiosResponse<{ data: Relation[] }> = await api.get( | ||
"/relations?limit=-1" | ||
); | ||
const relations = relationsRes.data.data; | ||
relations.forEach((relation) => { | ||
const oneField = collections[relation.meta.one_collection]?.fields.find( | ||
(field) => field.field === relation.meta.one_field | ||
); | ||
const manyField = collections[relation.meta.many_collection]?.fields.find( | ||
(field) => field.field === relation.meta.many_field | ||
); | ||
if (oneField) | ||
oneField.relation = { | ||
type: "many", | ||
collection: relation.meta.many_collection, | ||
}; | ||
if (manyField) | ||
manyField.relation = { | ||
type: "one", | ||
collection: relation.meta.one_collection, | ||
}; | ||
}); | ||
return collections; | ||
|
||
return gatherCollectionsData( | ||
collectionsResponse.data.data, | ||
fieldsResponse.data.data, | ||
relationsResponse.data.data, | ||
); | ||
} | ||
|
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { defineHook } from '@directus/extensions-sdk'; | ||
import generateTsTypes from "../lib/generate-types/ts"; | ||
import { ActionHandler, Collection, Field, Relation, SchemaOverview } from "@directus/types"; | ||
import { Collections } from '../lib/types'; | ||
import { gatherCollectionsData } from '../lib/generate-types/utils'; | ||
import * as fs from 'node:fs'; | ||
|
||
export default defineHook(({ action }, extCtx) => { | ||
const { services: { CollectionsService, FieldsService, RelationsService }, env, logger } = extCtx; | ||
|
||
let targetFiles: string | string[] = env.GENERATE_TYPES_SYNCED_TS_FILES; | ||
|
||
if (targetFiles == null || targetFiles.length === 0) { | ||
logger.info('No target file defined to automatically sync TypeScript types') | ||
return | ||
} | ||
|
||
if (! Array.isArray(targetFiles)) { | ||
targetFiles = [targetFiles] | ||
} | ||
|
||
const listCollections = async (schema: SchemaOverview) => { | ||
const collectionsService = new CollectionsService({schema}); | ||
const collections: Collection[] = await collectionsService.readByQuery(); | ||
|
||
const fieldsService = new FieldsService({schema}); | ||
const fields: Field[] = await fieldsService.readAll(); | ||
|
||
const relationsService = new RelationsService({schema}); | ||
const relations: Relation[] = await relationsService.readAll(); | ||
|
||
const collectionsData: Collections = await gatherCollectionsData( | ||
collections, | ||
fields, | ||
relations | ||
) | ||
|
||
let useIntersectionTypes = false; | ||
generateTsTypes(collectionsData, useIntersectionTypes).then((types) => { | ||
targetFiles.forEach((targetFile: string) => { | ||
writeToFile('./', targetFile, types) | ||
logger.info(`Types synced into ${targetFile}`) | ||
}) | ||
}); | ||
} | ||
|
||
const onChange: ActionHandler = async ({ }, { schema }) => { | ||
if (schema === null) { | ||
throw new Error('schema is null'); | ||
} | ||
listCollections(schema); | ||
} | ||
|
||
action('collections.create', onChange); | ||
action('collections.update', onChange); | ||
action('collections.delete', onChange); | ||
|
||
action('fields.create', onChange); | ||
action('fields.update', onChange); | ||
action('fields.delete', onChange); | ||
|
||
action('relations.create', onChange); | ||
action('relations.update', onChange); | ||
action('relations.delete', onChange); | ||
}); | ||
|
||
|
||
export function writeToFile(directoryPath: string, fileName: string, data: string) { | ||
try { | ||
fs.mkdirSync(directoryPath, {recursive: true}) | ||
} | ||
catch (e: any) { | ||
if (e.code != `EEXIST`) { | ||
throw e | ||
} | ||
} | ||
|
||
fs.writeFileSync(`${directoryPath}/${fileName}`, data) | ||
} |
File renamed without changes.
File renamed without changes.
9 changes: 6 additions & 3 deletions
9
...ypes-admin-module/lib/generateTypes/py.ts → src/lib/generate-types/py.ts
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
10 changes: 6 additions & 4 deletions
10
...ypes-admin-module/lib/generateTypes/ts.ts → src/lib/generate-types/ts.ts
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import type { Collections } from "../types"; | ||
import { warn } from "../console"; | ||
|
||
export async function gatherCollectionsData(rawCollections, rawFields , rawRelations) { | ||
|
||
const collections: Collections = {}; | ||
rawCollections | ||
.sort((a, b) => a.collection.localeCompare(b.collection)) | ||
.forEach( | ||
(collection) => | ||
(collections[collection.collection] = { ...collection, fields: [] }) | ||
); | ||
|
||
rawFields | ||
.sort((a, b) => a.field.localeCompare(b.field)) | ||
.forEach((field) => { | ||
if (!collections[field.collection]) { | ||
warn(`${field.collection} not found`); | ||
return; | ||
} | ||
collections[field.collection].fields.push(field); | ||
}); | ||
|
||
Object.keys(collections).forEach((key) => { | ||
if (collections[key].fields.length === 0) delete collections[key]; | ||
}); | ||
|
||
rawRelations.forEach((relation) => { | ||
const oneField = collections[relation.meta.one_collection]?.fields.find( | ||
(field) => field.field === relation.meta.one_field | ||
); | ||
const manyField = collections[relation.meta.many_collection]?.fields.find( | ||
(field) => field.field === relation.meta.many_field | ||
); | ||
if (oneField) | ||
oneField.relation = { | ||
type: "many", | ||
collection: relation.meta.many_collection, | ||
}; | ||
if (manyField) | ||
manyField.relation = { | ||
type: "one", | ||
collection: relation.meta.one_collection, | ||
}; | ||
}); | ||
|
||
return collections; | ||
} | ||
|
||
|
File renamed without changes.
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