Skip to content

Commit

Permalink
Merge pull request #83 from UoaWDCC/Feat/Pre-commit-hook
Browse files Browse the repository at this point in the history
Feat/pre commit hook
  • Loading branch information
GBHU753 authored Aug 6, 2024
2 parents 7312b87 + 6bf5d50 commit 93c1da6
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/full/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
}
},
"workspaceFolder": "/repo",
"postCreateCommand": "yarn install",
"postCreateCommand": "yarn install && yarn prepare",
"postStartCommand": "",
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
Expand Down
14 changes: 14 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh
# .husky/pre-commit

# Try to curl the URL and pipe the output to a file
curl http://0.0.0.0:8055/server/specs/oas -o ./backend/docs/api_docs.json

# Check if the curl command was successful
if [ $? -ne 0 ]; then
echo "Curl command failed are you in the dev-container? Aborting commit."
exit 1
fi

# If successful, proceed with the commit
echo "Curl command succeeded. Proceeding with commit."
1 change: 1 addition & 0 deletions backend/docs/api_docs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"openapi":"3.0.1","info":{"title":"Dynamic API Specification","description":"This is a dynamically generated API specification for all endpoints existing on the current project.","version":"10.13.1"},"servers":[{"url":"0.0.0.0:8055","description":"Your current Directus instance."}],"paths":{"/assets/{id}":{"get":{"tags":["Assets"],"operationId":"getAsset","summary":"Get an Asset","description":"Image typed files can be dynamically resized and transformed to fit any need.","parameters":[{"name":"id","in":"path","description":"The id of the file.","required":true,"schema":{"type":"string"}},{"name":"key","in":"query","description":"The key of the asset size configured in settings.","schema":{"type":"string"}},{"name":"transforms","in":"query","description":"A JSON array of image transformations","schema":{"type":"string"}},{"name":"download","in":"query","description":"Download the asset to your computer","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful request","content":{"text/plain":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/auth/login":{"post":{"summary":"Retrieve a Temporary Access Token","description":"Retrieve a Temporary Access Token","tags":["Authentication"],"operationId":"login","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","example":"[email protected]","description":"Email address of the user you're retrieving the access token for."},"password":{"type":"string","description":"Password of the user.","format":"password","example":"password"},"mode":{"type":"string","enum":["json","cookie","session"],"default":"json","description":"Whether to retrieve the refresh token in the JSON response, or in a httpOnly cookie."},"otp":{"type":"string","description":"The user's one-time-password (if MFA is enabled)."}}}}}},"responses":{"200":{"description":"Successful authentification","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"access_token":{"type":"string","example":"eyJhbGciOiJI..."},"expires":{"type":"integer","example":900},"refresh_token":{"type":"string","example":"yuOJkjdPXMd..."}}}}}}}}}}},"/auth/refresh":{"post":{"summary":"Refresh Token","description":"Refresh a Temporary Access Token.","tags":["Authentication"],"operationId":"refresh","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"refresh_token":{"type":"string","example":"eyJ0eXAiOiJKV...","description":"JWT access token you want to refresh. This token can't be expired."},"mode":{"type":"string","enum":["json","cookie","session"],"default":"json","description":"Whether to submit and retrieve the refresh token in the JSON response, or in a httpOnly cookie."}}}}}},"responses":{"200":{"description":"Successful request","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"access_token":{"type":"string","example":"eyJhbGciOiJI..."},"expires":{"type":"integer","example":900},"refresh_token":{"type":"string","example":"Gy-caJMpmGTA..."}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/auth/logout":{"post":{"summary":"Log Out","description":"Log Out","tags":["Authentication"],"operationId":"logout","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"refresh_token":{"type":"string","example":"eyJ0eXAiOiJKV...","description":"The refresh token to invalidate. If you have the refresh token in a cookie through /auth/login, you don't have to submit it here."},"mode":{"type":"string","enum":["json","cookie","session"],"description":"Whether the refresh token is submitted in the JSON response, or in a httpOnly cookie."}}}}}},"responses":{"200":{"description":"Request successful"}}}},"/auth/password/request":{"post":{"tags":["Authentication"],"operationId":"passwordRequest","summary":"Request a Password Reset","description":"Request a reset password email to be send.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","example":"[email protected]","description":"Email address of the user you're requesting a reset for."}}}}}},"responses":{"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/auth/password/reset":{"post":{"tags":["Authentication"],"operationId":"passwordReset","summary":"Reset a Password","description":"The request a password reset endpoint sends an email with a link to the admin app which in turn uses this endpoint to allow the user to reset their password.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["token","password"],"properties":{"token":{"type":"string","example":"eyJ0eXAiOiJKV1Qi...","description":"One-time use JWT token that is used to verify the user."},"password":{"type":"string","example":"password","format":"password","description":"New password for the user."}}}}}},"responses":{"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/auth/oauth":{"get":{"tags":["Authentication"],"operationId":"oauth","summary":"List OAuth Providers","description":"List configured OAuth providers.","responses":{"200":{"description":"Successful request","content":{"application/json":{"schema":{"type":"object","properties":{"public":{"type":"boolean"},"data":{"type":"array","example":["github","facebook"],"items":{"type":"string"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/auth/oauth/{provider}":{"get":{"summary":"Authenticated using an OAuth provider","description":"Start OAuth flow using the specified provider","tags":["Authentication"],"operationId":"oauthProvider","parameters":[{"name":"provider","in":"path","description":"Key of the activated OAuth provider.","required":true,"schema":{"type":"string"}},{"name":"redirect","in":"query","required":false,"description":"Where to redirect on successful login.<br/>If set the authentication details are set inside cookies otherwise a JSON is returned.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful request","content":{"application/json":{"schema":{"type":"object","properties":{"public":{"type":"boolean"},"data":{"type":"object","properties":{"token":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/server/info":{"get":{"summary":"System Info","description":"Perform a system status check and return the options.","operationId":"serverInfo","parameters":[{"description":"The first time you create a project, the provided token will be saved and required for subsequent project installs. It can also be found and configured in `/config/__api.json` on your server.","in":"query","name":"super_admin_token","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"type":"object"}},"type":"object"}}},"description":"Successful request"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"}},"tags":["Server"]}},"/server/ping":{"get":{"summary":"Ping","description":"Ping, pong. Ping.. pong.","operationId":"ping","responses":{"200":{"content":{"application/text":{"schema":{"type":"string","pattern":"pong","example":"pong"}}},"description":"Successful request"}},"tags":["Server"]}},"/items/Event":{"get":{"summary":"List Items","description":"List the Event items.","tags":["Items","ItemsEvent"],"operationId":"readItemsEvent","security":[{"Auth":[]}],"parameters":[{"$ref":"#/components/parameters/Fields"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Meta"},{"$ref":"#/components/parameters/Offset"},{"$ref":"#/components/parameters/Sort"},{"$ref":"#/components/parameters/Filter"},{"$ref":"#/components/parameters/Search"}],"responses":{"200":{"description":"Successful request","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","$ref":"#/components/schemas/ItemsEvent"}},"meta":{"$ref":"#/components/schemas/x-metadata"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/items/Event/{id}":{"get":{"summary":"Retrieve an Item","description":"Retrieve a single Event item by unique identifier.","tags":["Items","ItemsEvent"],"operationId":"readSingleItemsEvent","parameters":[{"$ref":"#/components/parameters/Fields"},{"$ref":"#/components/parameters/Meta"},{"$ref":"#/components/parameters/Version"},{"name":"id","description":"Index of the item.","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","description":"Incremental index of the item.","example":1},{"type":"string","description":"Unique identifier of the item.","example":"8cbb43fe-4cdf-4991-8352-c461779cec02"}]}}],"responses":{"200":{"description":"Successful request","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","$ref":"#/components/schemas/ItemsEvent"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/items/Executive":{"get":{"summary":"List Items","description":"List the Executive items.","tags":["Items","ItemsExecutive"],"operationId":"readItemsExecutive","security":[{"Auth":[]}],"parameters":[{"$ref":"#/components/parameters/Fields"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Meta"},{"$ref":"#/components/parameters/Offset"},{"$ref":"#/components/parameters/Sort"},{"$ref":"#/components/parameters/Filter"},{"$ref":"#/components/parameters/Search"}],"responses":{"200":{"description":"Successful request","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","$ref":"#/components/schemas/ItemsExecutive"}},"meta":{"$ref":"#/components/schemas/x-metadata"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"}}}},"/items/Executive/{id}":{"get":{"summary":"Retrieve an Item","description":"Retrieve a single Executive item by unique identifier.","tags":["Items","ItemsExecutive"],"operationId":"readSingleItemsExecutive","parameters":[{"$ref":"#/components/parameters/Fields"},{"$ref":"#/components/parameters/Meta"},{"$ref":"#/components/parameters/Version"},{"name":"id","description":"Index of the item.","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","description":"Incremental index of the item.","example":1},{"type":"string","description":"Unique identifier of the item.","example":"8cbb43fe-4cdf-4991-8352-c461779cec02"}]}}],"responses":{"200":{"description":"Successful request","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","$ref":"#/components/schemas/ItemsExecutive"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}}},"tags":[{"name":"Assets","description":"Image typed files can be dynamically resized and transformed to fit any need."},{"name":"Authentication","description":"All data within the platform is private by default. The public role can be configured to expose data without authentication, or you can pass an access token to the API to access private data."},{"name":"Server","description":"Access to where Directus runs. Allows you to make sure your server has everything needed to run the platform, and check what kind of latency we're dealing with."},{"name":"ItemsEvent","x-collection":"Event"},{"name":"ItemsExecutive","x-collection":"Executive"}],"components":{"schemas":{"Query":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string"},"description":"Control what fields are being returned in the object.","example":["*","*.*"]},"filter":{"type":"object","example":{"<field>":{"<operator>":"<value>"}}},"search":{"description":"Filter by items that contain the given search query in one of their fields.","type":"string"},"sort":{"type":"array","items":{"type":"string"},"description":"How to sort the returned items.","example":["-date_created"]},"limit":{"type":"number","description":"Set the maximum number of items that will be returned"},"offset":{"type":"number","description":"How many items to skip when fetching data."},"page":{"type":"number","description":"Cursor for use in pagination. Often used in combination with limit."},"deep":{"type":"object","description":"Deep allows you to set any of the other query parameters on a nested relational dataset.","example":{"related_articles":{"_limit":3}}}}},"x-metadata":{"type":"object","properties":{"total_count":{"description":"Returns the total item count of the collection you're querying.","type":"integer"},"filter_count":{"description":"Returns the item count of the collection you're querying, taking the current filter/search parameters into account.","type":"integer"}}},"ItemsEvent":{"type":"object","properties":{"id":{"nullable":false,"type":"integer"},"status":{"nullable":false,"type":"string"},"user_created":{"nullable":true,"type":"string"},"date_created":{"nullable":true,"type":"string","format":"timestamp"},"user_updated":{"nullable":true,"type":"string"},"date_updated":{"nullable":true,"type":"string","format":"timestamp"},"name":{"nullable":true,"type":"string"},"datetime":{"nullable":true,"type":"string","format":"date-time"},"price":{"nullable":true,"type":"string"},"description":{"nullable":true,"type":"string"},"note":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string","format":"uuid"},"venue":{"nullable":true}},"x-collection":"Event"},"ItemsExecutive":{"type":"object","properties":{"id":{"nullable":false,"type":"integer"},"status":{"nullable":false,"type":"string"},"user_created":{"nullable":true,"type":"string"},"date_created":{"nullable":true,"type":"string","format":"timestamp"},"user_updated":{"nullable":true,"type":"string"},"date_updated":{"nullable":true,"type":"string","format":"timestamp"},"name":{"nullable":true,"type":"string"},"description":{"nullable":true,"type":"string"},"title":{"nullable":true,"type":"string"},"image":{"nullable":true,"type":"string","format":"uuid"}},"x-collection":"Executive"}},"parameters":{"Id":{"description":"Index","name":"id","in":"path","required":true,"schema":{"type":"integer"}},"UUId":{"description":"Unique identifier for the object.","name":"id","in":"path","required":true,"schema":{"example":"8cbb43fe-4cdf-4991-8352-c461779cec02","type":"string"}},"Collection":{"description":"Collection of which you want to retrieve the items from.","name":"collection","in":"path","required":true,"schema":{"type":"string"}},"Search":{"description":"Filter by items that contain the given search query in one of their fields.","in":"query","name":"search","required":false,"schema":{"type":"string"}},"Page":{"description":"Cursor for use in pagination. Often used in combination with limit.","in":"query","name":"page","required":false,"schema":{"type":"integer"}},"Offset":{"description":"How many items to skip when fetching data.","in":"query","name":"offset","required":false,"schema":{"type":"integer"}},"Sort":{"description":"How to sort the returned items. `sort` is a CSV of fields used to sort the fetched items. Sorting defaults to ascending (ASC) order but a minus sign (` - `) can be used to reverse this to descending (DESC) order. Fields are prioritized by their order in the CSV. You can also use a ` ? ` to sort randomly.\n","in":"query","name":"sort","required":false,"explode":false,"schema":{"type":"array","items":{"type":"string"}}},"Meta":{"description":"What metadata to return in the response.","in":"query","name":"meta","required":false,"schema":{"type":"string"}},"Limit":{"description":"A limit on the number of objects that are returned.","in":"query","name":"limit","required":false,"schema":{"type":"integer"}},"Filter":{"description":"Select items in collection by given conditions.","in":"query","name":"filter","required":false,"content":{"application/json":{"schema":{"type":"object","example":{"<field>":{"<operator>":"<value>"}}}}}},"Fields":{"description":"Control what fields are being returned in the object.","in":"query","name":"fields","required":false,"explode":false,"schema":{"type":"array","items":{"type":"string"}}},"Export":{"name":"export","description":"Saves the API response to a file. Accepts one of \"csv\", \"json\", \"xml\", \"yaml\".","in":"query","required":false,"schema":{"type":"string","enum":["csv","json","xml","yaml"]}},"Version":{"name":"version","description":"Retrieve an item's state from a specific Content Version. The value corresponds to the \"key\" of the Content Version.\n","in":"query","required":false,"schema":{"type":"string"}}},"responses":{"NotFoundError":{"description":"Error: Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"integer","format":"int64"},"message":{"type":"string"}}}}}}}},"UnauthorizedError":{"description":"Error: Unauthorized request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"integer","format":"int64"},"message":{"type":"string"}}}}}}}}},"securitySchemes":{"KeyAuth":{"type":"apiKey","in":"query","name":"access_token"},"Auth":{"type":"apiKey","in":"header","name":"Authorization"}}}}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"dev:backend": "cd backend && yarn dev",
"bundle:docs": "cd backend && cd scripts && cd javascript && node api-json-gen.cjs",
"delete:api-client": "if [ -d frontend/src/api-client ]; then rm -r frontend/src/api-client; fi",
"generate:api-client": "yarn bundle:docs && yarn delete:api-client && openapi-generator-cli generate --openapitools openapitools.json"
"generate:api-client": "yarn bundle:docs && yarn delete:api-client && openapi-generator-cli generate --openapitools openapitools.json",
"prepare": "husky"
},
"keywords": [],
"author": "",
Expand All @@ -21,5 +22,8 @@
"dependencies": {
"@next/font": "^14.2.4",
"@openapitools/openapi-generator-cli": "^2.13.4"
},
"devDependencies": {
"husky": "^9.1.4"
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ [email protected]:
agent-base "^7.0.2"
debug "4"

husky@^9.1.4:
version "9.1.4"
resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.4.tgz#926fd19c18d345add5eab0a42b2b6d9a80259b34"
integrity sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==

iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
Expand Down

0 comments on commit 93c1da6

Please sign in to comment.