strapi-content-sync-pro 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.
- package/LICENSE +21 -0
- package/README.md +206 -0
- package/admin/src/components/ConfigTab.jsx +1038 -0
- package/admin/src/components/ContentTypesTab.jsx +160 -0
- package/admin/src/components/HelpTab.jsx +945 -0
- package/admin/src/components/LogsTab.jsx +136 -0
- package/admin/src/components/MediaTab.jsx +557 -0
- package/admin/src/components/SyncProfilesTab.jsx +715 -0
- package/admin/src/components/SyncTab.jsx +988 -0
- package/admin/src/index.js +31 -0
- package/admin/src/pages/App/index.jsx +129 -0
- package/admin/src/pluginId.js +3 -0
- package/package.json +84 -0
- package/server/src/bootstrap.js +151 -0
- package/server/src/config/index.js +5 -0
- package/server/src/content-types/index.js +7 -0
- package/server/src/content-types/sync-log/schema.json +24 -0
- package/server/src/controllers/alerts.js +59 -0
- package/server/src/controllers/config.js +292 -0
- package/server/src/controllers/content-type-discovery.js +9 -0
- package/server/src/controllers/dependencies.js +109 -0
- package/server/src/controllers/index.js +29 -0
- package/server/src/controllers/ping.js +7 -0
- package/server/src/controllers/sync-config.js +26 -0
- package/server/src/controllers/sync-enforcement.js +323 -0
- package/server/src/controllers/sync-execution.js +134 -0
- package/server/src/controllers/sync-log.js +18 -0
- package/server/src/controllers/sync-media.js +158 -0
- package/server/src/controllers/sync-profiles.js +182 -0
- package/server/src/controllers/sync.js +31 -0
- package/server/src/destroy.js +7 -0
- package/server/src/index.js +21 -0
- package/server/src/middlewares/verify-signature.js +32 -0
- package/server/src/register.js +7 -0
- package/server/src/routes/index.js +111 -0
- package/server/src/services/alerts.js +437 -0
- package/server/src/services/config.js +68 -0
- package/server/src/services/content-type-discovery.js +41 -0
- package/server/src/services/dependency-resolver.js +284 -0
- package/server/src/services/index.js +30 -0
- package/server/src/services/ping.js +7 -0
- package/server/src/services/sync-config.js +45 -0
- package/server/src/services/sync-enforcement.js +362 -0
- package/server/src/services/sync-execution.js +541 -0
- package/server/src/services/sync-log.js +56 -0
- package/server/src/services/sync-media.js +963 -0
- package/server/src/services/sync-profiles.js +380 -0
- package/server/src/services/sync.js +248 -0
- package/server/src/utils/applier.js +89 -0
- package/server/src/utils/comparator.js +83 -0
- package/server/src/utils/fetcher.js +142 -0
- package/server/src/utils/hmac.js +37 -0
- package/server/src/utils/pagination.js +51 -0
- package/server/src/utils/sync-guard.js +29 -0
- package/server/src/utils/sync-id.js +16 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const PLUGIN_ID = 'strapi-content-sync-pro';
|
|
4
|
+
|
|
5
|
+
module.exports = ({ strapi }) => ({
|
|
6
|
+
/**
|
|
7
|
+
* GET /sync-profiles
|
|
8
|
+
* List all sync profiles
|
|
9
|
+
*/
|
|
10
|
+
async find(ctx) {
|
|
11
|
+
try {
|
|
12
|
+
const profiles = await strapi.plugin(PLUGIN_ID).service('syncProfiles').getProfiles();
|
|
13
|
+
ctx.body = { data: profiles };
|
|
14
|
+
} catch (err) {
|
|
15
|
+
ctx.throw(500, err.message);
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* GET /sync-profiles/:id
|
|
21
|
+
* Get a single sync profile
|
|
22
|
+
*/
|
|
23
|
+
async findOne(ctx) {
|
|
24
|
+
const { id } = ctx.params;
|
|
25
|
+
try {
|
|
26
|
+
const profile = await strapi.plugin(PLUGIN_ID).service('syncProfiles').getProfile(id);
|
|
27
|
+
if (!profile) {
|
|
28
|
+
return ctx.throw(404, `Profile with id "${id}" not found`);
|
|
29
|
+
}
|
|
30
|
+
ctx.body = { data: profile };
|
|
31
|
+
} catch (err) {
|
|
32
|
+
ctx.throw(500, err.message);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* GET /sync-profiles/content-type/:uid
|
|
38
|
+
* Get all profiles for a content type
|
|
39
|
+
*/
|
|
40
|
+
async findByContentType(ctx) {
|
|
41
|
+
const { uid } = ctx.params;
|
|
42
|
+
try {
|
|
43
|
+
const profiles = await strapi.plugin(PLUGIN_ID).service('syncProfiles').getProfilesForContentType(uid);
|
|
44
|
+
ctx.body = { data: profiles };
|
|
45
|
+
} catch (err) {
|
|
46
|
+
ctx.throw(500, err.message);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* GET /sync-profiles/content-type/:uid/active
|
|
52
|
+
* Get active profile for a content type
|
|
53
|
+
*/
|
|
54
|
+
async findActiveByContentType(ctx) {
|
|
55
|
+
const { uid } = ctx.params;
|
|
56
|
+
try {
|
|
57
|
+
const profile = await strapi.plugin(PLUGIN_ID).service('syncProfiles').getActiveProfileForContentType(uid);
|
|
58
|
+
ctx.body = { data: profile };
|
|
59
|
+
} catch (err) {
|
|
60
|
+
ctx.throw(500, err.message);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* POST /sync-profiles
|
|
66
|
+
* Create a new sync profile
|
|
67
|
+
*/
|
|
68
|
+
async create(ctx) {
|
|
69
|
+
const body = ctx.request.body;
|
|
70
|
+
try {
|
|
71
|
+
const profile = await strapi.plugin(PLUGIN_ID).service('syncProfiles').createProfile(body);
|
|
72
|
+
ctx.body = { data: profile };
|
|
73
|
+
} catch (err) {
|
|
74
|
+
ctx.throw(400, err.message);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* POST /sync-profiles/auto-generate
|
|
80
|
+
* Auto-generate default profiles for a content type
|
|
81
|
+
*/
|
|
82
|
+
async autoGenerate(ctx) {
|
|
83
|
+
const { contentType } = ctx.request.body;
|
|
84
|
+
if (!contentType) {
|
|
85
|
+
return ctx.throw(400, 'contentType is required');
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const profiles = await strapi.plugin(PLUGIN_ID).service('syncProfiles').autoGenerateProfiles(contentType);
|
|
89
|
+
ctx.body = { data: profiles };
|
|
90
|
+
} catch (err) {
|
|
91
|
+
ctx.throw(400, err.message);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* POST /sync-profiles/simple
|
|
97
|
+
* Create a simple preset profile
|
|
98
|
+
*/
|
|
99
|
+
async createSimple(ctx) {
|
|
100
|
+
const { contentType, preset } = ctx.request.body;
|
|
101
|
+
if (!contentType) {
|
|
102
|
+
return ctx.throw(400, 'contentType is required');
|
|
103
|
+
}
|
|
104
|
+
if (!preset) {
|
|
105
|
+
return ctx.throw(400, 'preset is required');
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const profile = await strapi.plugin(PLUGIN_ID).service('syncProfiles').createSimpleProfile(contentType, preset);
|
|
109
|
+
ctx.body = { data: profile };
|
|
110
|
+
} catch (err) {
|
|
111
|
+
ctx.throw(400, err.message);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* PUT /sync-profiles/:id
|
|
117
|
+
* Update an existing sync profile
|
|
118
|
+
*/
|
|
119
|
+
async update(ctx) {
|
|
120
|
+
const { id } = ctx.params;
|
|
121
|
+
const body = ctx.request.body;
|
|
122
|
+
try {
|
|
123
|
+
const profile = await strapi.plugin(PLUGIN_ID).service('syncProfiles').updateProfile(id, body);
|
|
124
|
+
ctx.body = { data: profile };
|
|
125
|
+
} catch (err) {
|
|
126
|
+
if (err.message.includes('not found')) {
|
|
127
|
+
return ctx.throw(404, err.message);
|
|
128
|
+
}
|
|
129
|
+
ctx.throw(400, err.message);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* DELETE /sync-profiles/:id
|
|
135
|
+
* Delete a sync profile
|
|
136
|
+
*/
|
|
137
|
+
async delete(ctx) {
|
|
138
|
+
const { id } = ctx.params;
|
|
139
|
+
try {
|
|
140
|
+
const result = await strapi.plugin(PLUGIN_ID).service('syncProfiles').deleteProfile(id);
|
|
141
|
+
ctx.body = { data: result };
|
|
142
|
+
} catch (err) {
|
|
143
|
+
if (err.message.includes('not found')) {
|
|
144
|
+
return ctx.throw(404, err.message);
|
|
145
|
+
}
|
|
146
|
+
ctx.throw(500, err.message);
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* GET /content-type-schema/:uid
|
|
152
|
+
* Get schema/fields for a content type (for UI to display available fields)
|
|
153
|
+
*/
|
|
154
|
+
async getContentTypeSchema(ctx) {
|
|
155
|
+
const { uid } = ctx.params;
|
|
156
|
+
try {
|
|
157
|
+
const contentType = strapi.contentTypes[uid];
|
|
158
|
+
if (!contentType) {
|
|
159
|
+
return ctx.throw(404, `Content type "${uid}" not found`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const attributes = contentType.attributes || {};
|
|
163
|
+
const fields = Object.entries(attributes).map(([name, attr]) => ({
|
|
164
|
+
name,
|
|
165
|
+
type: attr.type,
|
|
166
|
+
required: attr.required || false,
|
|
167
|
+
relation: attr.type === 'relation' ? attr.relation : null,
|
|
168
|
+
target: attr.target || null,
|
|
169
|
+
}));
|
|
170
|
+
|
|
171
|
+
ctx.body = {
|
|
172
|
+
data: {
|
|
173
|
+
uid,
|
|
174
|
+
displayName: contentType.info?.displayName || uid,
|
|
175
|
+
fields,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
} catch (err) {
|
|
179
|
+
ctx.throw(500, err.message);
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
async syncNow(ctx) {
|
|
5
|
+
const syncService = strapi.plugin('strapi-content-sync-pro').service('sync');
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
const result = await syncService.syncNow();
|
|
9
|
+
ctx.body = { data: result };
|
|
10
|
+
} catch (err) {
|
|
11
|
+
return ctx.badRequest(err.message);
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
async receive(ctx) {
|
|
16
|
+
const { body } = ctx.request;
|
|
17
|
+
|
|
18
|
+
if (!body || !body.uid || !body.syncId) {
|
|
19
|
+
return ctx.badRequest('Missing uid, data, or syncId');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const syncService = strapi.plugin('strapi-content-sync-pro').service('sync');
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const result = await syncService.receiveRecord(body.uid, body.data || {}, body.syncId);
|
|
26
|
+
ctx.body = { data: result };
|
|
27
|
+
} catch (err) {
|
|
28
|
+
return ctx.badRequest(err.message);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const register = require('./register');
|
|
4
|
+
const bootstrap = require('./bootstrap');
|
|
5
|
+
const destroy = require('./destroy');
|
|
6
|
+
const config = require('./config');
|
|
7
|
+
const contentTypes = require('./content-types');
|
|
8
|
+
const controllers = require('./controllers');
|
|
9
|
+
const routes = require('./routes');
|
|
10
|
+
const services = require('./services');
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
register,
|
|
14
|
+
bootstrap,
|
|
15
|
+
destroy,
|
|
16
|
+
config,
|
|
17
|
+
routes,
|
|
18
|
+
controllers,
|
|
19
|
+
services,
|
|
20
|
+
contentTypes,
|
|
21
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { verifySignature } = require('../utils/hmac');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Koa middleware that validates the HMAC signature sent by a remote
|
|
7
|
+
* Strapi instance. Used on the /receive endpoint.
|
|
8
|
+
*/
|
|
9
|
+
module.exports = async (ctx, next) => {
|
|
10
|
+
const signature = ctx.request.headers['x-sync-signature'];
|
|
11
|
+
const timestamp = ctx.request.headers['x-sync-timestamp'];
|
|
12
|
+
|
|
13
|
+
if (!signature || !timestamp) {
|
|
14
|
+
return ctx.unauthorized('Missing x-sync-signature or x-sync-timestamp header');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const configService = strapi.plugin('strapi-content-sync-pro').service('config');
|
|
18
|
+
const serverConfig = await configService.getConfig({ safe: false });
|
|
19
|
+
|
|
20
|
+
if (!serverConfig || !serverConfig.sharedSecret) {
|
|
21
|
+
return ctx.unauthorized('Server not configured for sync');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const body = ctx.request.body || {};
|
|
25
|
+
const isValid = verifySignature(body, serverConfig.sharedSecret, signature, timestamp);
|
|
26
|
+
|
|
27
|
+
if (!isValid) {
|
|
28
|
+
return ctx.unauthorized('Invalid sync signature');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await next();
|
|
32
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const verifySignature = require('../middlewares/verify-signature');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Strapi v5 plugin routes MUST be split between:
|
|
7
|
+
* - content-api: exposed under /api/<plugin>/... (remote server calls)
|
|
8
|
+
* - admin: exposed under /<plugin>/... (local admin UI calls)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const contentApiRoutes = [
|
|
12
|
+
{ method: 'GET', path: '/ping', handler: 'ping.index', config: { policies: [], auth: false } },
|
|
13
|
+
{ method: 'GET', path: '/enforcement/local-info', handler: 'syncEnforcement.getLocalInfo', config: { policies: [] } },
|
|
14
|
+
{ method: 'GET', path: '/enforcement/schema/:uid', handler: 'syncEnforcement.getLocalSchema', config: { policies: [] } },
|
|
15
|
+
{ method: 'POST', path: '/receive', handler: 'sync.receive', config: { policies: [], auth: false, middlewares: [verifySignature] } },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const adminRoutes = [
|
|
19
|
+
// Config
|
|
20
|
+
{ method: 'GET', path: '/config', handler: 'config.get', config: { policies: [] } },
|
|
21
|
+
{ method: 'POST', path: '/config', handler: 'config.set', config: { policies: [] } },
|
|
22
|
+
{ method: 'POST', path: '/config/remote-login', handler: 'config.remoteLogin', config: { policies: [] } },
|
|
23
|
+
{ method: 'GET', path: '/config/test', handler: 'config.test', config: { policies: [] } },
|
|
24
|
+
|
|
25
|
+
// Content-type discovery
|
|
26
|
+
{ method: 'GET', path: '/content-types', handler: 'contentTypeDiscovery.find', config: { policies: [] } },
|
|
27
|
+
|
|
28
|
+
// Sync configuration
|
|
29
|
+
{ method: 'GET', path: '/sync-config', handler: 'syncConfig.get', config: { policies: [] } },
|
|
30
|
+
{ method: 'POST', path: '/sync-config', handler: 'syncConfig.set', config: { policies: [] } },
|
|
31
|
+
|
|
32
|
+
// Manual sync trigger
|
|
33
|
+
{ method: 'POST', path: '/sync-now', handler: 'sync.syncNow', config: { policies: [] } },
|
|
34
|
+
|
|
35
|
+
// Logs
|
|
36
|
+
{ method: 'GET', path: '/logs', handler: 'syncLog.find', config: { policies: [] } },
|
|
37
|
+
|
|
38
|
+
// Sync Profiles
|
|
39
|
+
{ method: 'GET', path: '/sync-profiles', handler: 'syncProfiles.find', config: { policies: [] } },
|
|
40
|
+
{ method: 'GET', path: '/sync-profiles/:id', handler: 'syncProfiles.findOne', config: { policies: [] } },
|
|
41
|
+
{ method: 'GET', path: '/sync-profiles/content-type/:uid', handler: 'syncProfiles.findByContentType', config: { policies: [] } },
|
|
42
|
+
{ method: 'GET', path: '/sync-profiles/content-type/:uid/active', handler: 'syncProfiles.findActiveByContentType', config: { policies: [] } },
|
|
43
|
+
{ method: 'POST', path: '/sync-profiles', handler: 'syncProfiles.create', config: { policies: [] } },
|
|
44
|
+
{ method: 'POST', path: '/sync-profiles/auto-generate', handler: 'syncProfiles.autoGenerate', config: { policies: [] } },
|
|
45
|
+
{ method: 'POST', path: '/sync-profiles/simple', handler: 'syncProfiles.createSimple', config: { policies: [] } },
|
|
46
|
+
{ method: 'PUT', path: '/sync-profiles/:id', handler: 'syncProfiles.update', config: { policies: [] } },
|
|
47
|
+
{ method: 'DELETE', path: '/sync-profiles/:id', handler: 'syncProfiles.delete', config: { policies: [] } },
|
|
48
|
+
{ method: 'GET', path: '/content-type-schema/:uid', handler: 'syncProfiles.getContentTypeSchema', config: { policies: [] } },
|
|
49
|
+
|
|
50
|
+
// Sync Execution
|
|
51
|
+
{ method: 'GET', path: '/sync-execution/settings', handler: 'syncExecution.getSettings', config: { policies: [] } },
|
|
52
|
+
{ method: 'GET', path: '/sync-execution/settings/:profileId', handler: 'syncExecution.getProfileSettings', config: { policies: [] } },
|
|
53
|
+
{ method: 'PUT', path: '/sync-execution/settings/:profileId', handler: 'syncExecution.updateProfileSettings', config: { policies: [] } },
|
|
54
|
+
{ method: 'GET', path: '/sync-execution/global-settings', handler: 'syncExecution.getGlobalSettings', config: { policies: [] } },
|
|
55
|
+
{ method: 'PUT', path: '/sync-execution/global-settings', handler: 'syncExecution.updateGlobalSettings', config: { policies: [] } },
|
|
56
|
+
{ method: 'POST', path: '/sync-execution/execute/:profileId', handler: 'syncExecution.executeProfile', config: { policies: [] } },
|
|
57
|
+
{ method: 'POST', path: '/sync-execution/execute-batch', handler: 'syncExecution.executeProfiles', config: { policies: [] } },
|
|
58
|
+
{ method: 'POST', path: '/sync-execution/execute-content-type/:uid', handler: 'syncExecution.executeContentType', config: { policies: [] } },
|
|
59
|
+
{ method: 'GET', path: '/sync-execution/status', handler: 'syncExecution.getStatus', config: { policies: [] } },
|
|
60
|
+
|
|
61
|
+
// Enforcement (admin-side)
|
|
62
|
+
{ method: 'GET', path: '/enforcement/settings', handler: 'syncEnforcement.getSettings', config: { policies: [] } },
|
|
63
|
+
{ method: 'PUT', path: '/enforcement/settings', handler: 'syncEnforcement.updateSettings', config: { policies: [] } },
|
|
64
|
+
{ method: 'GET', path: '/enforcement/remote-info', handler: 'syncEnforcement.getRemoteInfo', config: { policies: [] } },
|
|
65
|
+
{ method: 'GET', path: '/enforcement/check/:type', handler: 'syncEnforcement.runDiagnosticCheck', config: { policies: [] } },
|
|
66
|
+
{ method: 'POST', path: '/enforcement/check', handler: 'syncEnforcement.runChecks', config: { policies: [] } },
|
|
67
|
+
{ method: 'GET', path: '/enforcement/summary', handler: 'syncEnforcement.getSummary', config: { policies: [] } },
|
|
68
|
+
|
|
69
|
+
// Alerts
|
|
70
|
+
{ method: 'GET', path: '/alerts/settings', handler: 'alerts.getSettings', config: { policies: [] } },
|
|
71
|
+
{ method: 'PUT', path: '/alerts/settings', handler: 'alerts.updateSettings', config: { policies: [] } },
|
|
72
|
+
{ method: 'POST', path: '/alerts/test/:channel', handler: 'alerts.testChannel', config: { policies: [] } },
|
|
73
|
+
{ method: 'GET', path: '/alerts/stats', handler: 'alerts.getStats', config: { policies: [] } },
|
|
74
|
+
|
|
75
|
+
// Media sync
|
|
76
|
+
{ method: 'GET', path: '/media-sync/profiles', handler: 'syncMedia.getProfiles', config: { policies: [] } },
|
|
77
|
+
{ method: 'GET', path: '/media-sync/profiles/:id', handler: 'syncMedia.getProfile', config: { policies: [] } },
|
|
78
|
+
{ method: 'POST', path: '/media-sync/profiles', handler: 'syncMedia.createProfile', config: { policies: [] } },
|
|
79
|
+
{ method: 'PUT', path: '/media-sync/profiles/:id', handler: 'syncMedia.updateProfile', config: { policies: [] } },
|
|
80
|
+
{ method: 'DELETE', path: '/media-sync/profiles/:id', handler: 'syncMedia.deleteProfile', config: { policies: [] } },
|
|
81
|
+
{ method: 'POST', path: '/media-sync/profiles/:id/activate', handler: 'syncMedia.activateProfile', config: { policies: [] } },
|
|
82
|
+
{ method: 'POST', path: '/media-sync/profiles/:id/run', handler: 'syncMedia.runProfile', config: { policies: [] } },
|
|
83
|
+
{ method: 'POST', path: '/media-sync/run-active', handler: 'syncMedia.runActiveProfiles', config: { policies: [] } },
|
|
84
|
+
{ method: 'GET', path: '/media-sync/global-settings', handler: 'syncMedia.getGlobalSettings', config: { policies: [] } },
|
|
85
|
+
{ method: 'PUT', path: '/media-sync/global-settings', handler: 'syncMedia.updateGlobalSettings', config: { policies: [] } },
|
|
86
|
+
{ method: 'GET', path: '/media-sync/defaults', handler: 'syncMedia.getDefaults', config: { policies: [] } },
|
|
87
|
+
{ method: 'GET', path: '/media-sync/settings', handler: 'syncMedia.getSettings', config: { policies: [] } },
|
|
88
|
+
{ method: 'PUT', path: '/media-sync/settings', handler: 'syncMedia.updateSettings', config: { policies: [] } },
|
|
89
|
+
{ method: 'GET', path: '/media-sync/status', handler: 'syncMedia.getStatus', config: { policies: [] } },
|
|
90
|
+
{ method: 'POST', path: '/media-sync/test', handler: 'syncMedia.test', config: { policies: [] } },
|
|
91
|
+
{ method: 'POST', path: '/media-sync/run', handler: 'syncMedia.run', config: { policies: [] } },
|
|
92
|
+
|
|
93
|
+
// Dependencies
|
|
94
|
+
{ method: 'GET', path: '/dependencies/all', handler: 'dependencies.analyzeAll', config: { policies: [] } },
|
|
95
|
+
{ method: 'GET', path: '/dependencies/:uid', handler: 'dependencies.analyze', config: { policies: [] } },
|
|
96
|
+
{ method: 'GET', path: '/dependencies/:uid/graph', handler: 'dependencies.getGraph', config: { policies: [] } },
|
|
97
|
+
{ method: 'GET', path: '/dependencies/:uid/sync-order', handler: 'dependencies.getSyncOrder', config: { policies: [] } },
|
|
98
|
+
{ method: 'GET', path: '/dependencies/:uid/summary', handler: 'dependencies.getSummary', config: { policies: [] } },
|
|
99
|
+
{ method: 'POST', path: '/dependencies/clear-cache', handler: 'dependencies.clearCache', config: { policies: [] } },
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
'content-api': {
|
|
104
|
+
type: 'content-api',
|
|
105
|
+
routes: contentApiRoutes,
|
|
106
|
+
},
|
|
107
|
+
admin: {
|
|
108
|
+
type: 'admin',
|
|
109
|
+
routes: adminRoutes,
|
|
110
|
+
},
|
|
111
|
+
};
|