{"id":13650651,"url":"https://github.com/formfcw/directus-hook-library","last_synced_at":"2026-01-12T11:55:39.529Z","repository":{"id":204122382,"uuid":"710793601","full_name":"formfcw/directus-hook-library","owner":"formfcw","description":"A collection of customizable hooks for Directus","archived":false,"fork":false,"pushed_at":"2024-03-05T10:44:56.000Z","size":44,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-03-05T11:48:48.548Z","etag":null,"topics":["cascade","delete-unused","directus","directus-extension","env-settings","hooks","library","m2o","project-settings","replace-deleted-user-references","reset-hidden-fields"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/formfcw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-10-27T13:02:25.000Z","updated_at":"2024-04-14T17:56:03.129Z","dependencies_parsed_at":null,"dependency_job_id":"c704dcc3-7fbf-43c3-bc63-f757c5af2a82","html_url":"https://github.com/formfcw/directus-hook-library","commit_stats":null,"previous_names":["formfcw/directus-hook-library"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formfcw%2Fdirectus-hook-library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formfcw%2Fdirectus-hook-library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formfcw%2Fdirectus-hook-library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formfcw%2Fdirectus-hook-library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/formfcw","download_url":"https://codeload.github.com/formfcw/directus-hook-library/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223903146,"owners_count":17222494,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cascade","delete-unused","directus","directus-extension","env-settings","hooks","library","m2o","project-settings","replace-deleted-user-references","reset-hidden-fields"],"created_at":"2024-08-02T02:00:38.944Z","updated_at":"2026-01-12T11:55:39.470Z","avatar_url":"https://github.com/formfcw.png","language":"TypeScript","funding_links":[],"categories":["Extensions"],"sub_categories":["Extension Scripts"],"readme":"# Directus Hook Library\n\n[![NPM version](https://img.shields.io/npm/v/directus-hook-library)](https://www.npmjs.com/package/directus-hook-library)\n\nA collection of customizable hooks for Directus. This is not an extension, but a library of scripts that could be used inside a Directus hook extension.\n\n## Installation \u0026 Usage\n\nFirst [create a Directus Extension](https://docs.directus.io/extensions/creating-extensions.html) and during setup choose the extension type `hook`.\n\nInside the extension folder install `directus-hook-library`:\n\n```sh\nnpm install directus-hook-library\n```\n\nImport it in `src/index.ts`, like:\n\n```js\nimport { setProjectSettingsFromEnvVars } from \"directus-hook-library\";\n```\n\nHave a look at the examples below.\n\n\u003e _Tip:_ You can use multiple of these hook scripts inside the same Directus hook.\n\n## Hooks \u0026 Examples\n\n### `deleteUnusedM2OItems`\n\nUsed to delete related M2O items that loose their relation and should not be kept, which is not possible via directus itself. This makes sense for a M2O relation that is used like a O2O relation.\n\nDelete all `oneCollection` items that loose their relationship to a `manyCollections` item.\n\n**(!) Important**: You have to specify a (hidden) reverse relationship `O2M` in your `oneCollection` inside Directus to make this work.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\n```ts\n// src/index.ts\nimport { defineHook } from \"@directus/extensions-sdk\";\nimport { deleteUnusedM2OItems } from \"directus-hook-library\";\n\nexport default defineHook((register, context) =\u003e {\n    deleteUnusedM2OItems(register, context, {\n        oneCollection: \"meta_infos\",\n        manyCollections: {\n            pages: \"pages\",\n            posts: \"posts\",\n        },\n    });\n});\n```\n\n\u003c/details\u003e\n\n### `deleteUnusedM2AItems`\n\nUsed to delete related M2A items that loose their relation and should not be kept, which is not possible via directus itself.\n\nGoes through all `junctionCollections` and stores the keys for each found `anyCollection` item. Then deletes all `anyCollections` items that are not included in the stored keys.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\n```ts\n// src/index.ts\nimport { defineHook } from \"@directus/extensions-sdk\";\nimport {\n    toJunctionCollectionM2A,\n    toAnyCollectionM2A,\n    deleteUnusedM2AItems,\n} from \"directus-hook-library\";\n\nexport default defineHook((register, context) =\u003e {\n    deleteUnusedM2AItems(register, context, {\n        anyCollections: [\n            \"gallery\",\n            \"video\",\n            \"definition_list\",\n            \"related_content\",\n        ].map(toAnyCollectionM2A),\n        junctionCollections: [\"page_editor_nodes\", \"post_editor_nodes\"].map(\n            toJunctionCollectionM2A\n        ),\n    });\n});\n```\n\n**`toAnyCollectionM2A`** ... maps the array elements to objects of type `AnyCollection` with a default `key` field of `“id”`.\n\n**`toJunctionCollectionM2A`** ... maps the array elements to objects of type `JunctionCollection` with a default `foreignKey` field of `“item”` and a default `foreignCollection` field of `“collection”`\n\n\u003c/details\u003e\n\n### `preventDeletingM2AItems`\n\nUsed for M2A items to prevent their deletion, which is not possible via directus itself.\n\nGoes through all `junctionCollections` and searches for the `relatedCollection` items to delete. If found, prevents deletion.\n\n\u003e Find M2A items by searching the schema for `“one_allowed_collections”` and look for collections that are deletable/reachable by the app/user (`many_collection` goes to the `junctionCollections`)\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\n```ts\n// src/index.ts\nimport { defineHook } from \"@directus/extensions-sdk\";\nimport {\n    toJunctionCollectionM2A,\n    preventDeletingM2AItems,\n} from \"directus-hook-library\";\n\nexport default defineHook((register, context) =\u003e {\n    preventDeletingM2AItems(register, context, {\n        relatedCollections: [\"video\"],\n        junctionCollections: [\"page_editor_nodes\", \"post_editor_nodes\"].map(\n            toJunctionCollectionM2A\n        ),\n    });\n});\n```\n\n**`toJunctionCollectionM2A`** ... maps the array elements to objects of type `JunctionCollection` with a default `foreignKey` field of `“item”` and a default `foreignCollection` field of `“collection”`\n\n\u003c/details\u003e\n\n### `replaceDeletedUserReferences`\n\nThis replaces the reference to a deleted user with a reference to the current user in the directus_files collection.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\n```ts\n// src/index.ts\nimport { defineHook } from \"@directus/extensions-sdk\";\nimport { replaceDeletedUserReferences } from \"directus-hook-library\";\n\nexport default defineHook((register, context) =\u003e {\n    replaceDeletedUserReferences(register, context);\n});\n```\n\n\u003c/details\u003e\n\n### `resetFieldsHiddenByOption`\n\nSet fields to null that have a value but are hidden by a condition.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\n```ts\n// src/index.ts\nimport { defineHook } from \"@directus/extensions-sdk\";\nimport { resetFieldsHiddenByOption } from \"directus-hook-library\";\n\nexport default defineHook((register, context) =\u003e {\n    resetFieldsHiddenByOption(register, context, {\n        collection: \"conditional\",\n        optionsField: \"detail\",\n        resetGroups: [\n            {\n                not: [\"yes\"],\n                nullify: [\"title\", \"description\"],\n            },\n            {\n                not: [\"no\"],\n                nullify: [\"external_link\"],\n            },\n        ],\n    });\n});\n```\n\n\u003c/details\u003e\n\n### `setProjectSettingsFromEnvVars`\n\nUsed for setting project settings from ENV vars like, `PROJECT_URL`.\n\nThis overwrites the values for `settings` in the Project Settings when starting Directus.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\n```ts\n// src/index.ts\nimport { defineHook } from \"@directus/extensions-sdk\";\nimport { setProjectSettingsFromEnvVars } from \"directus-hook-library\";\n\nexport default defineHook((register, context) =\u003e {\n    setProjectSettingsFromEnvVars(register, context, [\n        \"project_name\",\n        \"project_descriptor\",\n        \"project_url\",\n    ]);\n});\n```\n\nFor ENV variables like:\n\n```.env\nPROJECT_NAME=Directus\nPROJECT_DESCRIPTOR=Hook\nPROJECT_URL=http://localhost:3000\n```\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformfcw%2Fdirectus-hook-library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fformfcw%2Fdirectus-hook-library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformfcw%2Fdirectus-hook-library/lists"}