@learnpack/learnpack 5.0.332 → 5.0.334

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.
@@ -2,7 +2,7 @@ import SessionCommand from "../utils/SessionCommand";
2
2
  export declare const handleAssetCreation: (sessionPayload: {
3
3
  token: string;
4
4
  rigobotToken: string;
5
- }, learnJson: any, selectedLang: string, learnpackDeployUrl: string, b64IndexReadme: string, all_translations?: string[]) => Promise<any>;
5
+ }, learnJson: any, selectedLang: string, learnpackDeployUrl: string, b64IndexReadme: string, academyId: number | undefined, all_translations?: string[]) => Promise<any>;
6
6
  declare class BuildCommand extends SessionCommand {
7
7
  static description: string;
8
8
  static flags: {
@@ -45,7 +45,7 @@ const getLocalizedValue = (translations, lang, fallbackLangs = ["en", "us"]) =>
45
45
  const first = firstKey ? translations[firstKey] : "";
46
46
  return typeof first === "string" ? first : "";
47
47
  };
48
- const handleAssetCreation = async (sessionPayload, learnJson, selectedLang, learnpackDeployUrl, b64IndexReadme, all_translations = []) => {
48
+ const handleAssetCreation = async (sessionPayload, learnJson, selectedLang, learnpackDeployUrl, b64IndexReadme, academyId, all_translations = []) => {
49
49
  const category = "uncategorized";
50
50
  try {
51
51
  const user = await api_1.default.validateToken(sessionPayload.token);
@@ -56,17 +56,31 @@ const handleAssetCreation = async (sessionPayload, learnJson, selectedLang, lear
56
56
  }
57
57
  let slug = (0, creatorUtilities_1.slugify)(assetTitle).slice(0, 47);
58
58
  slug = `${slug}-${selectedLang}`;
59
- const { exists } = await api_1.default.doesAssetExists(sessionPayload.token, slug);
59
+ const { exists, academyId: existingAcademyId } = await api_1.default.doesAssetExists(sessionPayload.token, slug);
60
+ // Compare academy IDs if asset exists and academyId is provided
61
+ if (exists &&
62
+ existingAcademyId !== undefined &&
63
+ academyId !== undefined &&
64
+ existingAcademyId !== academyId) {
65
+ console_1.default.warning(`Asset exists in academy ${existingAcademyId}, but attempting to publish to academy ${academyId}. ` +
66
+ `The asset will be updated in its current academy (${existingAcademyId}).`);
67
+ }
68
+ // const technologies: unknown[] = Array.isArray(learnJson?.technologies) ?
69
+ // learnJson.technologies :
70
+ // []
60
71
  if (!exists) {
61
72
  console_1.default.info("Asset does not exist in this academy, creating it");
62
- const asset = await api_1.default.createAsset(sessionPayload.token, {
73
+ const assetPayload = {
63
74
  slug: slug,
64
75
  title: assetTitle,
65
76
  lang: selectedLang,
66
77
  graded: true,
67
78
  description: assetDescription,
68
79
  learnpack_deploy_url: learnpackDeployUrl,
69
- technologies: learnJson.technologies.map((tech) => tech.toLowerCase().replace(/\s+/g, "-")),
80
+ // technologies: technologies.map((tech: unknown) =>
81
+ // String(tech).toLowerCase().replace(/\s+/g, "-")
82
+ // ),
83
+ technologies: [],
70
84
  url: learnpackDeployUrl,
71
85
  category: category,
72
86
  owner: user.id,
@@ -74,7 +88,11 @@ const handleAssetCreation = async (sessionPayload, learnJson, selectedLang, lear
74
88
  preview: learnJson.preview,
75
89
  readme_raw: b64IndexReadme,
76
90
  all_translations,
77
- });
91
+ };
92
+ if (academyId !== undefined) {
93
+ assetPayload.academy_id = academyId;
94
+ }
95
+ const asset = await api_1.default.createAsset(sessionPayload.token, assetPayload);
78
96
  try {
79
97
  await api_1.default.updateRigoPackage(sessionPayload.rigobotToken.trim(), learnJson.slug, {
80
98
  asset_id: asset.id,
@@ -108,7 +126,7 @@ const handleAssetCreation = async (sessionPayload, learnJson, selectedLang, lear
108
126
  }
109
127
  catch (error) {
110
128
  console_1.default.error("Error updating or creating asset:", error);
111
- return null;
129
+ throw error;
112
130
  }
113
131
  };
114
132
  exports.handleAssetCreation = handleAssetCreation;
@@ -132,13 +150,19 @@ const createMultiLangAssetFromDisk = async (sessionPayload, learnJson, deployUrl
132
150
  indexReadmeString = "";
133
151
  }
134
152
  const b64IndexReadme = Buffer.from(indexReadmeString).toString("base64");
135
- // eslint-disable-next-line no-await-in-loop
136
- const asset = await (0, exports.handleAssetCreation)(sessionPayload, learnJson, lang, deployUrl, b64IndexReadme, all_translations);
137
- if (!asset) {
138
- console_1.default.debug("Could not create/update asset for lang", lang);
139
- continue;
153
+ try {
154
+ // eslint-disable-next-line no-await-in-loop
155
+ const asset = await (0, exports.handleAssetCreation)(sessionPayload, learnJson, lang, deployUrl, b64IndexReadme, undefined, all_translations);
156
+ if (!asset) {
157
+ console_1.default.debug("Could not create/update asset for lang", lang);
158
+ continue;
159
+ }
160
+ all_translations.push(asset.slug);
161
+ }
162
+ catch (error) {
163
+ console_1.default.error("Error creating asset for language", lang, error);
164
+ // Continue with other languages
140
165
  }
141
- all_translations.push(asset.slug);
142
166
  }
143
167
  };
144
168
  const runAudit = (strict) => {
@@ -155,10 +155,12 @@ const cleanFormState = (formState) => {
155
155
  const cleanFormStateForSyllabus = (formState) => {
156
156
  return Object.assign(Object.assign({}, formState), { description: formState.description, technologies: formState.technologies, contentIndex: formState.contentIndex, purposse: undefined, duration: undefined, hasContentIndex: undefined, variables: undefined, currentStep: undefined, language: undefined, isCompleted: undefined });
157
157
  };
158
- const createMultiLangAsset = async (bucket, rigoToken, bcToken, courseSlug, courseJson, deployUrl) => {
158
+ const createMultiLangAsset = async (bucket, rigoToken, bcToken, courseSlug, courseJson, deployUrl, academyId) => {
159
+ var _a;
159
160
  const availableLangs = Object.keys(courseJson.title);
160
161
  console.log("AVAILABLE LANGUAGES to upload asset", availableLangs);
161
162
  const all_translations = [];
163
+ const errors = [];
162
164
  for (const lang of availableLangs) {
163
165
  // eslint-disable-next-line no-await-in-loop
164
166
  const indexReadme = await bucket.file(`courses/${courseSlug}/README${(0, creatorUtilities_1.getReadmeExtension)(lang)}`);
@@ -174,14 +176,28 @@ const createMultiLangAsset = async (bucket, rigoToken, bcToken, courseSlug, cour
174
176
  indexReadmeString = "";
175
177
  }
176
178
  const b64IndexReadme = buffer_1.Buffer.from(indexReadmeString).toString("base64");
177
- // eslint-disable-next-line no-await-in-loop
178
- const asset = await (0, publish_1.handleAssetCreation)({ token: bcToken, rigobotToken: rigoToken.trim() }, courseJson, lang, deployUrl, b64IndexReadme, all_translations);
179
- if (!asset) {
180
- console.log("No se pudo crear el asset, saltando idioma", lang);
181
- continue;
179
+ try {
180
+ // eslint-disable-next-line no-await-in-loop
181
+ const asset = await (0, publish_1.handleAssetCreation)({ token: bcToken, rigobotToken: rigoToken.trim() }, courseJson, lang, deployUrl, b64IndexReadme, academyId, all_translations);
182
+ if (!asset) {
183
+ errors.push({
184
+ lang,
185
+ error: { detail: "Failed to create asset", status_code: 500 },
186
+ });
187
+ console.log("No se pudo crear el asset, saltando idioma", lang);
188
+ continue;
189
+ }
190
+ all_translations.push(asset.slug);
191
+ }
192
+ catch (error) {
193
+ const errorData = error && typeof error === "object" && "response" in error ?
194
+ ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) || error :
195
+ error;
196
+ errors.push({ lang, error: errorData });
197
+ console.error(`Error creating asset for language ${lang}:`, error);
182
198
  }
183
- all_translations.push(asset.slug);
184
199
  }
200
+ return { errors };
185
201
  };
186
202
  const lessonCleaner = (lesson) => {
187
203
  return Object.assign(Object.assign({}, lesson), { duration: undefined, generated: undefined, status: undefined, translations: undefined, uid: undefined, initialContent: undefined, locked: undefined });
@@ -2907,12 +2923,30 @@ class ServeCommand extends SessionCommand_1.default {
2907
2923
  return res.status(500).json({ error: error.message });
2908
2924
  }
2909
2925
  });
2926
+ app.get("/actions/academies", async (req, res) => {
2927
+ try {
2928
+ const bcToken = req.header("x-breathecode-token");
2929
+ if (!bcToken) {
2930
+ return res
2931
+ .status(400)
2932
+ .json({
2933
+ error: "Authentication failed, missing breathecode token",
2934
+ });
2935
+ }
2936
+ const academies = await (0, api_1.listUserAcademies)(bcToken);
2937
+ return res.json(academies);
2938
+ }
2939
+ catch (error) {
2940
+ console.error("Error fetching academies:", error);
2941
+ return res.status(500).json({ error: error.message });
2942
+ }
2943
+ });
2910
2944
  app.post("/actions/publish/:slug", async (req, res) => {
2911
2945
  try {
2912
2946
  const { slug } = req.params;
2913
2947
  const rigoToken = req.header("x-rigo-token");
2914
2948
  const bcToken = req.header("x-breathecode-token");
2915
- // const { academyId, categoryId } = req.body
2949
+ const { academyId } = req.body;
2916
2950
  if (!rigoToken || !bcToken) {
2917
2951
  return res
2918
2952
  .status(400)
@@ -2998,10 +3032,13 @@ class ServeCommand extends SessionCommand_1.default {
2998
3032
  const rigoRes = await axios_1.default.post(`${api_1.RIGOBOT_HOST}/v1/learnpack/upload`, form, {
2999
3033
  headers: Object.assign(Object.assign({}, form.getHeaders()), { Authorization: "Token " + rigoToken.trim() }),
3000
3034
  });
3001
- await createMultiLangAsset(bucket, rigoToken, bcToken, slug, fullConfig.config, rigoRes.data.url);
3035
+ const assetResults = await createMultiLangAsset(bucket, rigoToken, bcToken, slug, fullConfig.config, rigoRes.data.url, academyId);
3002
3036
  rimraf.sync(tmpRoot);
3003
3037
  console.log("RigoRes", rigoRes.data);
3004
- return res.json({ url: rigoRes.data.url });
3038
+ return res.json({
3039
+ url: rigoRes.data.url,
3040
+ errors: assetResults.errors,
3041
+ });
3005
3042
  });
3006
3043
  archive.on("error", err => {
3007
3044
  console.error("ZIP Error:", err);
@@ -26,6 +26,7 @@ type TAssetMissing = {
26
26
  preview: string;
27
27
  readme_raw: string;
28
28
  all_translations: string[];
29
+ academy_id?: number;
29
30
  };
30
31
  export declare const createAsset: (token: string, asset: TAssetMissing) => Promise<any>;
31
32
  export declare const doesAssetExists: (token: string, assetSlug: string) => Promise<{
package/lib/utils/api.js CHANGED
@@ -358,10 +358,15 @@ const createAsset = async (token, asset) => {
358
358
  readme_raw: asset.readme_raw,
359
359
  all_translations: asset.all_translations,
360
360
  };
361
- const url = `https://breathecode.herokuapp.com/v1/registry/asset/me`;
361
+ let url = `https://breathecode.herokuapp.com/v1/registry/asset/me`;
362
362
  const headers = {
363
363
  Authorization: `Token ${token}`,
364
364
  };
365
+ // Use academy-specific endpoint if academy_id is provided
366
+ if (asset.academy_id !== undefined) {
367
+ url = `https://breathecode.herokuapp.com/v1/registry/academy/asset`;
368
+ headers.Academy = String(asset.academy_id);
369
+ }
365
370
  try {
366
371
  const response = await axios_1.default.post(url, body, { headers });
367
372
  return response.data;
@@ -373,6 +378,7 @@ const createAsset = async (token, asset) => {
373
378
  };
374
379
  exports.createAsset = createAsset;
375
380
  const doesAssetExists = async (token, assetSlug) => {
381
+ var _a, _b, _c;
376
382
  const url = `https://breathecode.herokuapp.com/v1/registry/asset/${assetSlug}`;
377
383
  const headers = {
378
384
  Authorization: `Token ${token}`,
@@ -380,11 +386,12 @@ const doesAssetExists = async (token, assetSlug) => {
380
386
  try {
381
387
  const response = await axios_1.default.get(url, { headers });
382
388
  if (response.status === 200) {
383
- return { exists: true };
389
+ const academyId = ((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.academy) === null || _b === void 0 ? void 0 : _b.id) || ((_c = response.data) === null || _c === void 0 ? void 0 : _c.academy_id);
390
+ return { exists: true, academyId };
384
391
  }
385
392
  return { exists: false };
386
393
  }
387
- catch (_a) {
394
+ catch (_d) {
388
395
  // console.error("Failed to get asset:", error)
389
396
  return { exists: false };
390
397
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@learnpack/learnpack",
3
3
  "description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
4
- "version": "5.0.332",
4
+ "version": "5.0.334",
5
5
  "author": "Alejandro Sanchez @alesanchezr",
6
6
  "contributors": [
7
7
  {
@@ -60,6 +60,7 @@ export const handleAssetCreation = async (
60
60
  selectedLang: string,
61
61
  learnpackDeployUrl: string,
62
62
  b64IndexReadme: string,
63
+ academyId: number | undefined,
63
64
  all_translations: string[] = []
64
65
  ) => {
65
66
  const category = "uncategorized"
@@ -82,20 +83,41 @@ export const handleAssetCreation = async (
82
83
  let slug = slugify(assetTitle).slice(0, 47)
83
84
  slug = `${slug}-${selectedLang}`
84
85
 
85
- const { exists } = await api.doesAssetExists(sessionPayload.token, slug)
86
+ const { exists, academyId: existingAcademyId } = await api.doesAssetExists(
87
+ sessionPayload.token,
88
+ slug
89
+ )
90
+
91
+ // Compare academy IDs if asset exists and academyId is provided
92
+ if (
93
+ exists &&
94
+ existingAcademyId !== undefined &&
95
+ academyId !== undefined &&
96
+ existingAcademyId !== academyId
97
+ ) {
98
+ Console.warning(
99
+ `Asset exists in academy ${existingAcademyId}, but attempting to publish to academy ${academyId}. ` +
100
+ `The asset will be updated in its current academy (${existingAcademyId}).`
101
+ )
102
+ }
103
+
104
+ // const technologies: unknown[] = Array.isArray(learnJson?.technologies) ?
105
+ // learnJson.technologies :
106
+ // []
86
107
 
87
108
  if (!exists) {
88
109
  Console.info("Asset does not exist in this academy, creating it")
89
- const asset = await api.createAsset(sessionPayload.token, {
110
+ const assetPayload: any = {
90
111
  slug: slug,
91
112
  title: assetTitle,
92
113
  lang: selectedLang,
93
114
  graded: true,
94
115
  description: assetDescription,
95
116
  learnpack_deploy_url: learnpackDeployUrl,
96
- technologies: learnJson.technologies.map((tech: string) =>
97
- tech.toLowerCase().replace(/\s+/g, "-")
98
- ),
117
+ // technologies: technologies.map((tech: unknown) =>
118
+ // String(tech).toLowerCase().replace(/\s+/g, "-")
119
+ // ),
120
+ technologies: [],
99
121
  url: learnpackDeployUrl,
100
122
  category: category,
101
123
  owner: user.id,
@@ -103,7 +125,12 @@ export const handleAssetCreation = async (
103
125
  preview: learnJson.preview,
104
126
  readme_raw: b64IndexReadme,
105
127
  all_translations,
106
- })
128
+ }
129
+ if (academyId !== undefined) {
130
+ assetPayload.academy_id = academyId
131
+ }
132
+
133
+ const asset = await api.createAsset(sessionPayload.token, assetPayload)
107
134
  try {
108
135
  await api.updateRigoPackage(
109
136
  sessionPayload.rigobotToken.trim(),
@@ -145,7 +172,7 @@ export const handleAssetCreation = async (
145
172
  return asset
146
173
  } catch (error) {
147
174
  Console.error("Error updating or creating asset:", error)
148
- return null
175
+ throw error
149
176
  }
150
177
  }
151
178
 
@@ -182,22 +209,28 @@ const createMultiLangAssetFromDisk = async (
182
209
 
183
210
  const b64IndexReadme = Buffer.from(indexReadmeString).toString("base64")
184
211
 
185
- // eslint-disable-next-line no-await-in-loop
186
- const asset = await handleAssetCreation(
187
- sessionPayload,
188
- learnJson,
189
- lang,
190
- deployUrl,
191
- b64IndexReadme,
192
- all_translations
193
- )
212
+ try {
213
+ // eslint-disable-next-line no-await-in-loop
214
+ const asset = await handleAssetCreation(
215
+ sessionPayload,
216
+ learnJson,
217
+ lang,
218
+ deployUrl,
219
+ b64IndexReadme,
220
+ undefined,
221
+ all_translations
222
+ )
194
223
 
195
- if (!asset) {
196
- Console.debug("Could not create/update asset for lang", lang)
197
- continue
198
- }
224
+ if (!asset) {
225
+ Console.debug("Could not create/update asset for lang", lang)
226
+ continue
227
+ }
199
228
 
200
- all_translations.push(asset.slug)
229
+ all_translations.push(asset.slug)
230
+ } catch (error) {
231
+ Console.error("Error creating asset for language", lang, error)
232
+ // Continue with other languages
233
+ }
201
234
  }
202
235
  }
203
236
 
@@ -49,7 +49,11 @@ import {
49
49
  // import { handleAssetCreation } from "./publish"
50
50
  import axios from "axios"
51
51
  import * as FormData from "form-data"
52
- import api, { RIGOBOT_HOST, RIGOBOT_REALTIME_HOST } from "../utils/api"
52
+ import api, {
53
+ RIGOBOT_HOST,
54
+ RIGOBOT_REALTIME_HOST,
55
+ listUserAcademies,
56
+ } from "../utils/api"
53
57
  import {
54
58
  createUploadMiddleware,
55
59
  minutesToISO8601Duration,
@@ -279,12 +283,14 @@ const createMultiLangAsset = async (
279
283
  bcToken: string,
280
284
  courseSlug: string,
281
285
  courseJson: any,
282
- deployUrl: string
283
- ) => {
286
+ deployUrl: string,
287
+ academyId?: number
288
+ ): Promise<{ errors: Array<{ lang: string; error: any }> }> => {
284
289
  const availableLangs = Object.keys(courseJson.title)
285
290
  console.log("AVAILABLE LANGUAGES to upload asset", availableLangs)
286
291
 
287
292
  const all_translations: string[] = []
293
+ const errors: Array<{ lang: string; error: any }> = []
288
294
 
289
295
  for (const lang of availableLangs) {
290
296
  // eslint-disable-next-line no-await-in-loop
@@ -304,23 +310,39 @@ const createMultiLangAsset = async (
304
310
 
305
311
  const b64IndexReadme = Buffer.from(indexReadmeString).toString("base64")
306
312
 
307
- // eslint-disable-next-line no-await-in-loop
308
- const asset = await handleAssetCreation(
309
- { token: bcToken, rigobotToken: rigoToken.trim() },
310
- courseJson,
311
- lang,
312
- deployUrl,
313
- b64IndexReadme,
314
- all_translations
315
- )
313
+ try {
314
+ // eslint-disable-next-line no-await-in-loop
315
+ const asset = await handleAssetCreation(
316
+ { token: bcToken, rigobotToken: rigoToken.trim() },
317
+ courseJson,
318
+ lang,
319
+ deployUrl,
320
+ b64IndexReadme,
321
+ academyId,
322
+ all_translations
323
+ )
316
324
 
317
- if (!asset) {
318
- console.log("No se pudo crear el asset, saltando idioma", lang)
319
- continue
320
- }
325
+ if (!asset) {
326
+ errors.push({
327
+ lang,
328
+ error: { detail: "Failed to create asset", status_code: 500 },
329
+ })
330
+ console.log("No se pudo crear el asset, saltando idioma", lang)
331
+ continue
332
+ }
321
333
 
322
- all_translations.push(asset.slug)
334
+ all_translations.push(asset.slug)
335
+ } catch (error) {
336
+ const errorData =
337
+ error && typeof error === "object" && "response" in error ?
338
+ (error as any).response?.data || error :
339
+ error
340
+ errors.push({ lang, error: errorData })
341
+ console.error(`Error creating asset for language ${lang}:`, error)
342
+ }
323
343
  }
344
+
345
+ return { errors }
324
346
  }
325
347
 
326
348
  const lessonCleaner = (lesson: Lesson) => {
@@ -4233,12 +4255,32 @@ class ServeCommand extends SessionCommand {
4233
4255
  }
4234
4256
  )
4235
4257
 
4258
+ app.get("/actions/academies", async (req, res) => {
4259
+ try {
4260
+ const bcToken = req.header("x-breathecode-token")
4261
+
4262
+ if (!bcToken) {
4263
+ return res
4264
+ .status(400)
4265
+ .json({
4266
+ error: "Authentication failed, missing breathecode token",
4267
+ })
4268
+ }
4269
+
4270
+ const academies = await listUserAcademies(bcToken)
4271
+ return res.json(academies)
4272
+ } catch (error) {
4273
+ console.error("Error fetching academies:", error)
4274
+ return res.status(500).json({ error: (error as Error).message })
4275
+ }
4276
+ })
4277
+
4236
4278
  app.post("/actions/publish/:slug", async (req, res) => {
4237
4279
  try {
4238
4280
  const { slug } = req.params
4239
4281
  const rigoToken = req.header("x-rigo-token")
4240
4282
  const bcToken = req.header("x-breathecode-token")
4241
- // const { academyId, categoryId } = req.body
4283
+ const { academyId } = req.body
4242
4284
 
4243
4285
  if (!rigoToken || !bcToken) {
4244
4286
  return res
@@ -4360,18 +4402,22 @@ class ServeCommand extends SessionCommand {
4360
4402
  }
4361
4403
  )
4362
4404
 
4363
- await createMultiLangAsset(
4405
+ const assetResults = await createMultiLangAsset(
4364
4406
  bucket,
4365
4407
  rigoToken,
4366
4408
  bcToken,
4367
4409
  slug,
4368
4410
  fullConfig.config,
4369
- rigoRes.data.url
4411
+ rigoRes.data.url,
4412
+ academyId
4370
4413
  )
4371
4414
 
4372
4415
  rimraf.sync(tmpRoot)
4373
4416
  console.log("RigoRes", rigoRes.data)
4374
- return res.json({ url: rigoRes.data.url })
4417
+ return res.json({
4418
+ url: rigoRes.data.url,
4419
+ errors: assetResults.errors,
4420
+ })
4375
4421
  })
4376
4422
 
4377
4423
  archive.on("error", err => {
package/src/utils/api.ts CHANGED
@@ -431,10 +431,11 @@ type TAssetMissing = {
431
431
  preview: string;
432
432
  readme_raw: string;
433
433
  all_translations: string[];
434
+ academy_id?: number;
434
435
  };
435
436
 
436
437
  export const createAsset = async (token: string, asset: TAssetMissing) => {
437
- const body = {
438
+ const body: any = {
438
439
  slug: asset.slug,
439
440
  title: asset.title,
440
441
  lang: asset.lang,
@@ -462,11 +463,18 @@ export const createAsset = async (token: string, asset: TAssetMissing) => {
462
463
  readme_raw: asset.readme_raw,
463
464
  all_translations: asset.all_translations,
464
465
  }
465
- const url = `https://breathecode.herokuapp.com/v1/registry/asset/me`
466
- const headers = {
466
+
467
+ let url = `https://breathecode.herokuapp.com/v1/registry/asset/me`
468
+ const headers: any = {
467
469
  Authorization: `Token ${token}`,
468
470
  }
469
471
 
472
+ // Use academy-specific endpoint if academy_id is provided
473
+ if (asset.academy_id !== undefined) {
474
+ url = `https://breathecode.herokuapp.com/v1/registry/academy/asset`
475
+ headers.Academy = String(asset.academy_id)
476
+ }
477
+
470
478
  try {
471
479
  const response = await axios.post(url, body, { headers })
472
480
  return response.data
@@ -489,7 +497,8 @@ export const doesAssetExists = async (
489
497
  try {
490
498
  const response = await axios.get(url, { headers })
491
499
  if (response.status === 200) {
492
- return { exists: true }
500
+ const academyId = response.data?.academy?.id || response.data?.academy_id
501
+ return { exists: true, academyId }
493
502
  }
494
503
 
495
504
  return { exists: false }