@orange-soft/strapi-deployment-trigger 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +116 -0
  2. package/admin/jsconfig.json +10 -0
  3. package/admin/src/components/Initializer.jsx +18 -0
  4. package/admin/src/components/PluginIcon.jsx +5 -0
  5. package/admin/src/index.js +49 -0
  6. package/admin/src/pages/App.jsx +17 -0
  7. package/admin/src/pages/HomePage.jsx +241 -0
  8. package/admin/src/pages/SettingsPage.jsx +370 -0
  9. package/admin/src/pluginId.js +1 -0
  10. package/admin/src/translations/en.json +3 -0
  11. package/admin/src/utils/getTranslation.js +5 -0
  12. package/dist/_chunks/App-3JntxPYv.js +520 -0
  13. package/dist/_chunks/App-C0Byi5W1.mjs +520 -0
  14. package/dist/_chunks/en-BDvOU5UD.js +6 -0
  15. package/dist/_chunks/en-DdBZuj6F.mjs +6 -0
  16. package/dist/_chunks/index-C18aSW5z.mjs +70 -0
  17. package/dist/_chunks/index-CqpMwL_C.js +69 -0
  18. package/dist/admin/index.js +3 -0
  19. package/dist/admin/index.mjs +4 -0
  20. package/dist/server/index.js +264 -0
  21. package/dist/server/index.mjs +265 -0
  22. package/package.json +84 -0
  23. package/server/jsconfig.json +10 -0
  24. package/server/src/bootstrap.js +5 -0
  25. package/server/src/config/index.js +4 -0
  26. package/server/src/content-types/index.js +1 -0
  27. package/server/src/controllers/controller.js +95 -0
  28. package/server/src/controllers/index.js +5 -0
  29. package/server/src/destroy.js +5 -0
  30. package/server/src/index.js +31 -0
  31. package/server/src/middlewares/index.js +1 -0
  32. package/server/src/policies/index.js +1 -0
  33. package/server/src/register.js +5 -0
  34. package/server/src/routes/admin/index.js +37 -0
  35. package/server/src/routes/content-api/index.js +14 -0
  36. package/server/src/routes/index.js +9 -0
  37. package/server/src/services/index.js +5 -0
  38. package/server/src/services/service.js +124 -0
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ const bootstrap = ({ strapi }) => {
3
+ };
4
+ const destroy = ({ strapi }) => {
5
+ };
6
+ const register = ({ strapi }) => {
7
+ };
8
+ const config = {
9
+ default: {},
10
+ validator() {
11
+ }
12
+ };
13
+ const contentTypes = {};
14
+ const PLUGIN_ID$1 = "deployment-trigger";
15
+ const getService = (strapi) => strapi.plugin(PLUGIN_ID$1).service("service");
16
+ const controller = ({ strapi }) => ({
17
+ index(ctx) {
18
+ ctx.body = getService(strapi).getWelcomeMessage();
19
+ },
20
+ async getSettings(ctx) {
21
+ const settings = await getService(strapi).getSettings();
22
+ ctx.body = { data: settings };
23
+ },
24
+ async saveSettings(ctx) {
25
+ const { data } = ctx.request.body;
26
+ const settings = await getService(strapi).saveSettings(data);
27
+ ctx.body = { data: settings };
28
+ },
29
+ async getStatus(ctx) {
30
+ const service2 = getService(strapi);
31
+ const settings = await service2.getSettings();
32
+ const configured = await service2.isConfigured();
33
+ const hasToken = await service2.hasToken();
34
+ const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
35
+ ctx.body = {
36
+ data: {
37
+ configured,
38
+ hasToken,
39
+ settings,
40
+ parsed: { owner, repo }
41
+ // Include parsed values for display
42
+ }
43
+ };
44
+ },
45
+ async trigger(ctx) {
46
+ const service2 = getService(strapi);
47
+ const githubToken = await service2.getToken();
48
+ if (!githubToken) {
49
+ return ctx.badRequest("GitHub token is not configured. Please add it in Settings.");
50
+ }
51
+ const settings = await service2.getSettings();
52
+ const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
53
+ if (!owner || !repo) {
54
+ return ctx.badRequest("GitHub repository URL is not configured or invalid. Please configure it in Settings.");
55
+ }
56
+ const { workflow = settings.workflow, branch = settings.branch } = ctx.request.body || {};
57
+ const url = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/dispatches`;
58
+ try {
59
+ const response = await fetch(url, {
60
+ method: "POST",
61
+ headers: {
62
+ Accept: "application/vnd.github.v3+json",
63
+ Authorization: `Bearer ${githubToken}`,
64
+ "Content-Type": "application/json"
65
+ },
66
+ body: JSON.stringify({ ref: branch })
67
+ });
68
+ if (!response.ok) {
69
+ const errorText = await response.text();
70
+ strapi.log.error(`GitHub API error: ${response.status} - ${errorText}`);
71
+ return ctx.badRequest(`GitHub API error: ${response.status} - ${errorText}`);
72
+ }
73
+ strapi.log.info(`Deployment triggered for ${owner}/${repo} on branch ${branch}`);
74
+ const actionsUrl = `https://github.com/${owner}/${repo}/actions`;
75
+ ctx.body = {
76
+ data: {
77
+ success: true,
78
+ message: `Deployment triggered successfully for ${owner}/${repo}`,
79
+ repository: `${owner}/${repo}`,
80
+ workflow,
81
+ branch,
82
+ actionsUrl
83
+ }
84
+ };
85
+ } catch (error) {
86
+ strapi.log.error("Error triggering deployment:", error);
87
+ return ctx.badRequest(`Failed to trigger deployment: ${error.message}`);
88
+ }
89
+ }
90
+ });
91
+ const controllers = {
92
+ controller
93
+ };
94
+ const middlewares = {};
95
+ const policies = {};
96
+ const contentAPIRoutes = () => ({
97
+ type: "content-api",
98
+ routes: [
99
+ {
100
+ method: "GET",
101
+ path: "/",
102
+ // name of the controller file & the method.
103
+ handler: "controller.index",
104
+ config: {
105
+ policies: []
106
+ }
107
+ }
108
+ ]
109
+ });
110
+ const adminAPIRoutes = () => ({
111
+ type: "admin",
112
+ routes: [
113
+ {
114
+ method: "GET",
115
+ path: "/settings",
116
+ handler: "controller.getSettings",
117
+ config: {
118
+ policies: []
119
+ }
120
+ },
121
+ {
122
+ method: "PUT",
123
+ path: "/settings",
124
+ handler: "controller.saveSettings",
125
+ config: {
126
+ policies: []
127
+ }
128
+ },
129
+ {
130
+ method: "GET",
131
+ path: "/status",
132
+ handler: "controller.getStatus",
133
+ config: {
134
+ policies: []
135
+ }
136
+ },
137
+ {
138
+ method: "POST",
139
+ path: "/trigger",
140
+ handler: "controller.trigger",
141
+ config: {
142
+ policies: []
143
+ }
144
+ }
145
+ ]
146
+ });
147
+ const routes = {
148
+ "content-api": contentAPIRoutes,
149
+ admin: adminAPIRoutes
150
+ };
151
+ const PLUGIN_ID = "deployment-trigger";
152
+ const STORE_KEY = "settings";
153
+ const DEFAULT_SETTINGS = {
154
+ repoUrl: "",
155
+ workflow: "deploy.yml",
156
+ branch: "master"
157
+ };
158
+ const service = ({ strapi }) => ({
159
+ getWelcomeMessage() {
160
+ return "Welcome to Strapi Deployment Trigger";
161
+ },
162
+ maskToken(token) {
163
+ if (!token || token.length < 20) return null;
164
+ const head = token.slice(0, 15);
165
+ const tail = token.slice(-4);
166
+ return `${head}...${tail}`;
167
+ },
168
+ parseRepoUrl(repoUrl) {
169
+ if (!repoUrl) return { owner: null, repo: null };
170
+ try {
171
+ const url = new URL(repoUrl);
172
+ const parts = url.pathname.split("/").filter(Boolean);
173
+ if (parts.length >= 2) {
174
+ return { owner: parts[0], repo: parts[1] };
175
+ }
176
+ } catch (e) {
177
+ }
178
+ return { owner: null, repo: null };
179
+ },
180
+ async getSettings() {
181
+ const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
182
+ const dbSettings = await store.get({ key: STORE_KEY });
183
+ const envToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
184
+ if (dbSettings && dbSettings.repoUrl) {
185
+ const token2 = dbSettings.githubToken || envToken;
186
+ return {
187
+ ...dbSettings,
188
+ githubToken: void 0,
189
+ // Never expose full token
190
+ hasToken: !!token2,
191
+ maskedToken: this.maskToken(token2)
192
+ };
193
+ }
194
+ const pluginConfig = strapi.config.get(`plugin::${PLUGIN_ID}`) || {};
195
+ if (pluginConfig.githubOwner && pluginConfig.githubRepo) {
196
+ return {
197
+ repoUrl: `https://github.com/${pluginConfig.githubOwner}/${pluginConfig.githubRepo}`,
198
+ workflow: pluginConfig.workflow || DEFAULT_SETTINGS.workflow,
199
+ branch: pluginConfig.branch || DEFAULT_SETTINGS.branch,
200
+ hasToken: !!envToken,
201
+ maskedToken: this.maskToken(envToken)
202
+ };
203
+ }
204
+ const token = dbSettings?.githubToken || envToken;
205
+ return {
206
+ ...DEFAULT_SETTINGS,
207
+ ...dbSettings,
208
+ githubToken: void 0,
209
+ hasToken: !!token,
210
+ maskedToken: this.maskToken(token)
211
+ };
212
+ },
213
+ async saveSettings(settings) {
214
+ const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
215
+ const existingSettings = await store.get({ key: STORE_KEY }) || {};
216
+ const settingsToSave = {
217
+ repoUrl: settings.repoUrl,
218
+ workflow: settings.workflow || DEFAULT_SETTINGS.workflow,
219
+ branch: settings.branch || DEFAULT_SETTINGS.branch,
220
+ // Only update token if a new one is provided
221
+ githubToken: settings.githubToken || existingSettings.githubToken
222
+ };
223
+ await store.set({ key: STORE_KEY, value: settingsToSave });
224
+ return {
225
+ ...settingsToSave,
226
+ githubToken: void 0,
227
+ hasToken: !!settingsToSave.githubToken || !!process.env.GITHUB_PERSONAL_ACCESS_TOKEN
228
+ };
229
+ },
230
+ async getToken() {
231
+ const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
232
+ const dbSettings = await store.get({ key: STORE_KEY });
233
+ if (dbSettings?.githubToken) {
234
+ return dbSettings.githubToken;
235
+ }
236
+ return process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
237
+ },
238
+ async isConfigured() {
239
+ const settings = await this.getSettings();
240
+ const hasToken = await this.getToken();
241
+ const { owner, repo } = this.parseRepoUrl(settings.repoUrl);
242
+ return !!(owner && repo && hasToken);
243
+ },
244
+ async hasToken() {
245
+ const token = await this.getToken();
246
+ return !!token;
247
+ }
248
+ });
249
+ const services = {
250
+ service
251
+ };
252
+ const index = {
253
+ bootstrap,
254
+ destroy,
255
+ register,
256
+ config,
257
+ controllers,
258
+ contentTypes,
259
+ middlewares,
260
+ policies,
261
+ routes,
262
+ services
263
+ };
264
+ module.exports = index;
@@ -0,0 +1,265 @@
1
+ const bootstrap = ({ strapi }) => {
2
+ };
3
+ const destroy = ({ strapi }) => {
4
+ };
5
+ const register = ({ strapi }) => {
6
+ };
7
+ const config = {
8
+ default: {},
9
+ validator() {
10
+ }
11
+ };
12
+ const contentTypes = {};
13
+ const PLUGIN_ID$1 = "deployment-trigger";
14
+ const getService = (strapi) => strapi.plugin(PLUGIN_ID$1).service("service");
15
+ const controller = ({ strapi }) => ({
16
+ index(ctx) {
17
+ ctx.body = getService(strapi).getWelcomeMessage();
18
+ },
19
+ async getSettings(ctx) {
20
+ const settings = await getService(strapi).getSettings();
21
+ ctx.body = { data: settings };
22
+ },
23
+ async saveSettings(ctx) {
24
+ const { data } = ctx.request.body;
25
+ const settings = await getService(strapi).saveSettings(data);
26
+ ctx.body = { data: settings };
27
+ },
28
+ async getStatus(ctx) {
29
+ const service2 = getService(strapi);
30
+ const settings = await service2.getSettings();
31
+ const configured = await service2.isConfigured();
32
+ const hasToken = await service2.hasToken();
33
+ const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
34
+ ctx.body = {
35
+ data: {
36
+ configured,
37
+ hasToken,
38
+ settings,
39
+ parsed: { owner, repo }
40
+ // Include parsed values for display
41
+ }
42
+ };
43
+ },
44
+ async trigger(ctx) {
45
+ const service2 = getService(strapi);
46
+ const githubToken = await service2.getToken();
47
+ if (!githubToken) {
48
+ return ctx.badRequest("GitHub token is not configured. Please add it in Settings.");
49
+ }
50
+ const settings = await service2.getSettings();
51
+ const { owner, repo } = service2.parseRepoUrl(settings.repoUrl);
52
+ if (!owner || !repo) {
53
+ return ctx.badRequest("GitHub repository URL is not configured or invalid. Please configure it in Settings.");
54
+ }
55
+ const { workflow = settings.workflow, branch = settings.branch } = ctx.request.body || {};
56
+ const url = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/dispatches`;
57
+ try {
58
+ const response = await fetch(url, {
59
+ method: "POST",
60
+ headers: {
61
+ Accept: "application/vnd.github.v3+json",
62
+ Authorization: `Bearer ${githubToken}`,
63
+ "Content-Type": "application/json"
64
+ },
65
+ body: JSON.stringify({ ref: branch })
66
+ });
67
+ if (!response.ok) {
68
+ const errorText = await response.text();
69
+ strapi.log.error(`GitHub API error: ${response.status} - ${errorText}`);
70
+ return ctx.badRequest(`GitHub API error: ${response.status} - ${errorText}`);
71
+ }
72
+ strapi.log.info(`Deployment triggered for ${owner}/${repo} on branch ${branch}`);
73
+ const actionsUrl = `https://github.com/${owner}/${repo}/actions`;
74
+ ctx.body = {
75
+ data: {
76
+ success: true,
77
+ message: `Deployment triggered successfully for ${owner}/${repo}`,
78
+ repository: `${owner}/${repo}`,
79
+ workflow,
80
+ branch,
81
+ actionsUrl
82
+ }
83
+ };
84
+ } catch (error) {
85
+ strapi.log.error("Error triggering deployment:", error);
86
+ return ctx.badRequest(`Failed to trigger deployment: ${error.message}`);
87
+ }
88
+ }
89
+ });
90
+ const controllers = {
91
+ controller
92
+ };
93
+ const middlewares = {};
94
+ const policies = {};
95
+ const contentAPIRoutes = () => ({
96
+ type: "content-api",
97
+ routes: [
98
+ {
99
+ method: "GET",
100
+ path: "/",
101
+ // name of the controller file & the method.
102
+ handler: "controller.index",
103
+ config: {
104
+ policies: []
105
+ }
106
+ }
107
+ ]
108
+ });
109
+ const adminAPIRoutes = () => ({
110
+ type: "admin",
111
+ routes: [
112
+ {
113
+ method: "GET",
114
+ path: "/settings",
115
+ handler: "controller.getSettings",
116
+ config: {
117
+ policies: []
118
+ }
119
+ },
120
+ {
121
+ method: "PUT",
122
+ path: "/settings",
123
+ handler: "controller.saveSettings",
124
+ config: {
125
+ policies: []
126
+ }
127
+ },
128
+ {
129
+ method: "GET",
130
+ path: "/status",
131
+ handler: "controller.getStatus",
132
+ config: {
133
+ policies: []
134
+ }
135
+ },
136
+ {
137
+ method: "POST",
138
+ path: "/trigger",
139
+ handler: "controller.trigger",
140
+ config: {
141
+ policies: []
142
+ }
143
+ }
144
+ ]
145
+ });
146
+ const routes = {
147
+ "content-api": contentAPIRoutes,
148
+ admin: adminAPIRoutes
149
+ };
150
+ const PLUGIN_ID = "deployment-trigger";
151
+ const STORE_KEY = "settings";
152
+ const DEFAULT_SETTINGS = {
153
+ repoUrl: "",
154
+ workflow: "deploy.yml",
155
+ branch: "master"
156
+ };
157
+ const service = ({ strapi }) => ({
158
+ getWelcomeMessage() {
159
+ return "Welcome to Strapi Deployment Trigger";
160
+ },
161
+ maskToken(token) {
162
+ if (!token || token.length < 20) return null;
163
+ const head = token.slice(0, 15);
164
+ const tail = token.slice(-4);
165
+ return `${head}...${tail}`;
166
+ },
167
+ parseRepoUrl(repoUrl) {
168
+ if (!repoUrl) return { owner: null, repo: null };
169
+ try {
170
+ const url = new URL(repoUrl);
171
+ const parts = url.pathname.split("/").filter(Boolean);
172
+ if (parts.length >= 2) {
173
+ return { owner: parts[0], repo: parts[1] };
174
+ }
175
+ } catch (e) {
176
+ }
177
+ return { owner: null, repo: null };
178
+ },
179
+ async getSettings() {
180
+ const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
181
+ const dbSettings = await store.get({ key: STORE_KEY });
182
+ const envToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
183
+ if (dbSettings && dbSettings.repoUrl) {
184
+ const token2 = dbSettings.githubToken || envToken;
185
+ return {
186
+ ...dbSettings,
187
+ githubToken: void 0,
188
+ // Never expose full token
189
+ hasToken: !!token2,
190
+ maskedToken: this.maskToken(token2)
191
+ };
192
+ }
193
+ const pluginConfig = strapi.config.get(`plugin::${PLUGIN_ID}`) || {};
194
+ if (pluginConfig.githubOwner && pluginConfig.githubRepo) {
195
+ return {
196
+ repoUrl: `https://github.com/${pluginConfig.githubOwner}/${pluginConfig.githubRepo}`,
197
+ workflow: pluginConfig.workflow || DEFAULT_SETTINGS.workflow,
198
+ branch: pluginConfig.branch || DEFAULT_SETTINGS.branch,
199
+ hasToken: !!envToken,
200
+ maskedToken: this.maskToken(envToken)
201
+ };
202
+ }
203
+ const token = dbSettings?.githubToken || envToken;
204
+ return {
205
+ ...DEFAULT_SETTINGS,
206
+ ...dbSettings,
207
+ githubToken: void 0,
208
+ hasToken: !!token,
209
+ maskedToken: this.maskToken(token)
210
+ };
211
+ },
212
+ async saveSettings(settings) {
213
+ const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
214
+ const existingSettings = await store.get({ key: STORE_KEY }) || {};
215
+ const settingsToSave = {
216
+ repoUrl: settings.repoUrl,
217
+ workflow: settings.workflow || DEFAULT_SETTINGS.workflow,
218
+ branch: settings.branch || DEFAULT_SETTINGS.branch,
219
+ // Only update token if a new one is provided
220
+ githubToken: settings.githubToken || existingSettings.githubToken
221
+ };
222
+ await store.set({ key: STORE_KEY, value: settingsToSave });
223
+ return {
224
+ ...settingsToSave,
225
+ githubToken: void 0,
226
+ hasToken: !!settingsToSave.githubToken || !!process.env.GITHUB_PERSONAL_ACCESS_TOKEN
227
+ };
228
+ },
229
+ async getToken() {
230
+ const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
231
+ const dbSettings = await store.get({ key: STORE_KEY });
232
+ if (dbSettings?.githubToken) {
233
+ return dbSettings.githubToken;
234
+ }
235
+ return process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
236
+ },
237
+ async isConfigured() {
238
+ const settings = await this.getSettings();
239
+ const hasToken = await this.getToken();
240
+ const { owner, repo } = this.parseRepoUrl(settings.repoUrl);
241
+ return !!(owner && repo && hasToken);
242
+ },
243
+ async hasToken() {
244
+ const token = await this.getToken();
245
+ return !!token;
246
+ }
247
+ });
248
+ const services = {
249
+ service
250
+ };
251
+ const index = {
252
+ bootstrap,
253
+ destroy,
254
+ register,
255
+ config,
256
+ controllers,
257
+ contentTypes,
258
+ middlewares,
259
+ policies,
260
+ routes,
261
+ services
262
+ };
263
+ export {
264
+ index as default
265
+ };
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@orange-soft/strapi-deployment-trigger",
3
+ "version": "1.0.0",
4
+ "description": "Strapi v5 plugin to trigger GitHub Actions workflow deployments from the admin panel",
5
+ "license": "MIT",
6
+ "author": "Justin Moh <moh@os.my>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/orange-soft/strapi-deployment-trigger.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/orange-soft/strapi-deployment-trigger/issues"
13
+ },
14
+ "homepage": "https://github.com/orange-soft/strapi-deployment-trigger#readme",
15
+ "keywords": [
16
+ "strapi",
17
+ "strapi-plugin",
18
+ "strapi-v5",
19
+ "deployment",
20
+ "github-actions",
21
+ "workflow",
22
+ "deploy",
23
+ "ci-cd"
24
+ ],
25
+ "type": "commonjs",
26
+ "exports": {
27
+ "./package.json": "./package.json",
28
+ "./strapi-admin": {
29
+ "source": "./admin/src/index.js",
30
+ "import": "./dist/admin/index.mjs",
31
+ "require": "./dist/admin/index.js",
32
+ "default": "./dist/admin/index.js"
33
+ },
34
+ "./strapi-server": {
35
+ "source": "./server/src/index.js",
36
+ "import": "./dist/server/index.mjs",
37
+ "require": "./dist/server/index.js",
38
+ "default": "./dist/server/index.js"
39
+ }
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "admin",
44
+ "server"
45
+ ],
46
+ "scripts": {
47
+ "build": "strapi-plugin build",
48
+ "watch": "strapi-plugin watch",
49
+ "watch:link": "strapi-plugin watch:link",
50
+ "verify": "strapi-plugin verify",
51
+ "prepublishOnly": "npm run build"
52
+ },
53
+ "dependencies": {
54
+ "@strapi/design-system": "^2.0.0-rc.30",
55
+ "@strapi/icons": "^2.0.0-rc.30",
56
+ "react-intl": "^8.0.8"
57
+ },
58
+ "devDependencies": {
59
+ "@strapi/strapi": "^5.0.0",
60
+ "@strapi/sdk-plugin": "^5.0.0",
61
+ "prettier": "^3.0.0",
62
+ "react": "^18.0.0",
63
+ "react-dom": "^18.0.0",
64
+ "react-router-dom": "^6.0.0",
65
+ "styled-components": "^6.0.0"
66
+ },
67
+ "peerDependencies": {
68
+ "@strapi/strapi": "^5.0.0",
69
+ "react": "^18.0.0",
70
+ "react-dom": "^18.0.0",
71
+ "react-router-dom": "^6.0.0",
72
+ "styled-components": "^6.0.0"
73
+ },
74
+ "strapi": {
75
+ "kind": "plugin",
76
+ "name": "deployment-trigger",
77
+ "displayName": "Deployment Trigger",
78
+ "description": "Trigger GitHub Actions deployment from admin panel"
79
+ },
80
+ "engines": {
81
+ "node": ">=18.0.0 <=22.x.x",
82
+ "npm": ">=6.0.0"
83
+ }
84
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es6",
4
+ "module": "commonjs",
5
+ "allowSyntheticDefaultImports": true,
6
+ "esModuleInterop": true
7
+ },
8
+ "include": ["./src/**/*.js"],
9
+ "exclude": ["node_modules"]
10
+ }
@@ -0,0 +1,5 @@
1
+ const bootstrap = ({ strapi }) => {
2
+ // bootstrap phase
3
+ };
4
+
5
+ export default bootstrap;
@@ -0,0 +1,4 @@
1
+ export default {
2
+ default: {},
3
+ validator() {},
4
+ };
@@ -0,0 +1 @@
1
+ export default {};