directus-template-cli 0.1.5 → 0.3.0-beta.1

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 (132) hide show
  1. package/README.md +27 -3
  2. package/dist/commands/apply.d.ts +1 -1
  3. package/dist/commands/apply.js +62 -51
  4. package/dist/commands/extract.d.ts +7 -0
  5. package/dist/commands/extract.js +54 -0
  6. package/dist/lib/extract/extract-assets.d.ts +3 -0
  7. package/dist/lib/extract/extract-assets.js +49 -0
  8. package/dist/lib/extract/extract-content.d.ts +3 -0
  9. package/dist/lib/extract/extract-content.js +33 -0
  10. package/dist/lib/extract/extract-from-endpoint.d.ts +4 -0
  11. package/dist/lib/extract/extract-from-endpoint.js +23 -0
  12. package/dist/lib/extract/extract-schema.d.ts +1 -0
  13. package/dist/lib/extract/extract-schema.js +29 -0
  14. package/dist/lib/extract/index.d.ts +1 -0
  15. package/dist/lib/extract/index.js +47 -0
  16. package/dist/lib/extract/public-permissions.d.ts +1 -0
  17. package/dist/lib/extract/public-permissions.js +21 -0
  18. package/dist/lib/load/index.js +31 -28
  19. package/dist/lib/load/load-folders.js +12 -4
  20. package/dist/lib/load/load-presets.js +19 -8
  21. package/dist/lib/load/load-public-permissions.d.ts +2 -1
  22. package/dist/lib/load/load-public-permissions.js +11 -5
  23. package/dist/lib/utils/auth.d.ts +2 -0
  24. package/dist/lib/utils/auth.js +34 -0
  25. package/dist/lib/utils/read-templates.d.ts +2 -1
  26. package/dist/lib/utils/read-templates.js +25 -20
  27. package/dist/lib/utils/template-defaults.d.ts +2 -0
  28. package/dist/lib/utils/template-defaults.js +37 -0
  29. package/dist/lib/utils/write-to-file.d.ts +1 -1
  30. package/dist/lib/utils/write-to-file.js +13 -9
  31. package/oclif.manifest.json +15 -1
  32. package/package.json +3 -2
  33. package/templates/agencyos/README.md +11 -0
  34. package/templates/agencyos/package.json +11 -0
  35. package/templates/agencyos/src/assets/004e37f7-765e-4339-8d44-987729e47898.png +0 -0
  36. package/templates/agencyos/src/assets/08177527-b867-47e9-b5d5-eab146b3cdba.jpg +0 -0
  37. package/templates/agencyos/src/assets/08242513-ca8f-471f-b69b-82703a19d1e5.svg +14 -0
  38. package/templates/agencyos/src/assets/0dfe66dd-ceba-4dca-8907-03b2dda49443.svg +1 -0
  39. package/templates/agencyos/src/assets/12e02b82-b4a4-4aaf-8ca4-e73c20a41c26.jpeg +0 -0
  40. package/templates/agencyos/src/assets/18bf5269-9986-48c7-b607-01b77283df3b.png +0 -0
  41. package/templates/agencyos/src/assets/1f19dd72-a433-481d-9b51-e3cc8e4f33d3.svg +1 -0
  42. package/templates/agencyos/src/assets/1f69c0b8-19b7-49d7-b420-bedad577a079.png +0 -0
  43. package/templates/agencyos/src/assets/270fa8d1-45a3-4fcb-87d2-27a0248f1daf.jpg +0 -0
  44. package/templates/agencyos/src/assets/27f55be1-7ef5-47c4-87ba-ab9a060ab270.jpeg +0 -0
  45. package/templates/agencyos/src/assets/35a67f1b-d401-4300-a503-b8e583186f2a.svg +11 -0
  46. package/templates/agencyos/src/assets/3eff7dc2-445a-47c5-9503-3f600ecdb5c6.jpeg +0 -0
  47. package/templates/agencyos/src/assets/4b31c98e-ec03-4b91-bb18-ef55dd199638.jpg +0 -0
  48. package/templates/agencyos/src/assets/50aa7259-f9ae-4aa5-aea0-f5f698ce3f4f.png +0 -0
  49. package/templates/agencyos/src/assets/643faffb-d41d-48ad-9050-881cf495cbb6.jpg +0 -0
  50. package/templates/agencyos/src/assets/6464e61f-455a-4b47-b623-bb12e5251dfe.jpeg +0 -0
  51. package/templates/agencyos/src/assets/6789bc72-ab83-40bf-8152-d6f2bafbc2a8.png +0 -0
  52. package/templates/agencyos/src/assets/68103296-6634-4d66-918a-04b09afe6621.jpeg +0 -0
  53. package/templates/agencyos/src/assets/690c2042-e3ad-46f4-9cd8-095a7b3a1df7.svg +3 -0
  54. package/templates/agencyos/src/assets/6a1ca349-d7ab-4f43-9284-c61671e145f2.svg +22 -0
  55. package/templates/agencyos/src/assets/6dad2008-3af5-407e-827e-da5744223181.svg +1 -0
  56. package/templates/agencyos/src/assets/7775c53a-6c2c-453d-8c22-8b5445121d10.jpeg +0 -0
  57. package/templates/agencyos/src/assets/7a5b47f6-d648-48f9-bf93-4bfafda48940.png +0 -0
  58. package/templates/agencyos/src/assets/87fc0e81-45e4-4c05-8e9a-8e5c759d7aae.png +0 -0
  59. package/templates/agencyos/src/assets/8f748634-d77b-4985-b27e-7e1f3559881a.jpeg +0 -0
  60. package/templates/agencyos/src/assets/9778a2b4-27de-4035-af5a-f58897578787.png +0 -0
  61. package/templates/agencyos/src/assets/a104c031-6ad2-4148-ace6-052e28cfda0b.svg +1 -0
  62. package/templates/agencyos/src/assets/b3038911-da85-4865-8035-e48522bcbb8c.svg +4 -0
  63. package/templates/agencyos/src/assets/bbc40e9b-c107-49d4-9c4b-05821816d457.jpg +0 -0
  64. package/templates/agencyos/src/assets/c983bd13-da09-4c90-8e65-ae6a92093df8.png +0 -0
  65. package/templates/agencyos/src/assets/d0130348-9ead-49d0-b8e7-871cd43921a0.svg +1 -0
  66. package/templates/agencyos/src/assets/d4fd6edc-4cc5-48c1-8bc7-e646924bbdca.jpeg +0 -0
  67. package/templates/agencyos/src/assets/d598a4c0-4e9a-44a3-a72e-49564e34a432.jpg +0 -0
  68. package/templates/agencyos/src/assets/dfa90758-9700-49e4-8fa2-b6cd074811b7.png +0 -0
  69. package/templates/agencyos/src/assets/e15ca910-1567-4f15-b5a0-b802da67f228.jpg +0 -0
  70. package/templates/agencyos/src/assets/f1693c44-52e4-4fae-a7d2-b3153a34eb72.jpg +0 -0
  71. package/templates/agencyos/src/collections.json +1983 -0
  72. package/templates/agencyos/src/content/block_cardgroup.json +14 -0
  73. package/templates/agencyos/src/content/block_cardgroup_cards.json +1 -0
  74. package/templates/agencyos/src/content/block_cardgroup_posts.json +32 -0
  75. package/templates/agencyos/src/content/block_columns.json +21 -0
  76. package/templates/agencyos/src/content/block_columns_rows.json +47 -0
  77. package/templates/agencyos/src/content/block_cta.json +15 -0
  78. package/templates/agencyos/src/content/block_faqs.json +45 -0
  79. package/templates/agencyos/src/content/block_form.json +26 -0
  80. package/templates/agencyos/src/content/block_gallery.json +14 -0
  81. package/templates/agencyos/src/content/block_gallery_files.json +38 -0
  82. package/templates/agencyos/src/content/block_hero.json +124 -0
  83. package/templates/agencyos/src/content/block_html.json +1 -0
  84. package/templates/agencyos/src/content/block_logocloud.json +13 -0
  85. package/templates/agencyos/src/content/block_logocloud_files.json +56 -0
  86. package/templates/agencyos/src/content/block_quote.json +11 -0
  87. package/templates/agencyos/src/content/block_richtext.json +32 -0
  88. package/templates/agencyos/src/content/block_steps.json +14 -0
  89. package/templates/agencyos/src/content/block_steps_items.json +26 -0
  90. package/templates/agencyos/src/content/block_team.json +8 -0
  91. package/templates/agencyos/src/content/block_testimonials.json +12 -0
  92. package/templates/agencyos/src/content/block_testimonials_items.json +26 -0
  93. package/templates/agencyos/src/content/block_video.json +10 -0
  94. package/templates/agencyos/src/content/blog_settings.json +8 -0
  95. package/templates/agencyos/src/content/categories.json +38 -0
  96. package/templates/agencyos/src/content/chat_config.json +39 -0
  97. package/templates/agencyos/src/content/conversations.json +11 -0
  98. package/templates/agencyos/src/content/events.json +1 -0
  99. package/templates/agencyos/src/content/forms.json +92 -0
  100. package/templates/agencyos/src/content/globals.json +64 -0
  101. package/templates/agencyos/src/content/help_articles.json +152 -0
  102. package/templates/agencyos/src/content/help_collections.json +42 -0
  103. package/templates/agencyos/src/content/help_feedback.json +14 -0
  104. package/templates/agencyos/src/content/inbox.json +1 -0
  105. package/templates/agencyos/src/content/messages.json +1 -0
  106. package/templates/agencyos/src/content/metrics.json +1 -0
  107. package/templates/agencyos/src/content/navigation.json +30 -0
  108. package/templates/agencyos/src/content/navigation_items.json +155 -0
  109. package/templates/agencyos/src/content/pages.json +107 -0
  110. package/templates/agencyos/src/content/pages_blocks.json +310 -0
  111. package/templates/agencyos/src/content/posts.json +110 -0
  112. package/templates/agencyos/src/content/projects.json +70 -0
  113. package/templates/agencyos/src/content/projects_files.json +1 -0
  114. package/templates/agencyos/src/content/projects_settings.json +6 -0
  115. package/templates/agencyos/src/content/redirects.json +12 -0
  116. package/templates/agencyos/src/content/seo.json +497 -0
  117. package/templates/agencyos/src/content/team.json +109 -0
  118. package/templates/agencyos/src/content/testimonials.json +50 -0
  119. package/templates/agencyos/src/dashboards.json +25 -0
  120. package/templates/agencyos/src/fields.json +28516 -0
  121. package/templates/agencyos/src/files.json +830 -0
  122. package/templates/agencyos/src/flows.json +134 -0
  123. package/templates/agencyos/src/folders.json +52 -0
  124. package/templates/agencyos/src/operations.json +214 -0
  125. package/templates/agencyos/src/panels.json +383 -0
  126. package/templates/agencyos/src/permissions.json +1047 -0
  127. package/templates/agencyos/src/presets.json +2213 -0
  128. package/templates/agencyos/src/public-permissions.json +663 -0
  129. package/templates/agencyos/src/roles.json +62 -0
  130. package/templates/agencyos/src/schema/snapshot.json +19519 -0
  131. package/templates/agencyos/src/settings.json +77 -0
  132. package/templates/agencyos/src/users.json +170 -0
package/README.md CHANGED
@@ -1,19 +1,43 @@
1
1
  # Directus Template CLI
2
2
 
3
- A CLI tool to apply Directus "templates" to a blank Directus instance.
3
+ A CLI tool to make applying or extracting Directus "templates" a little easier...well a lot easier.
4
4
 
5
- Note: This is a pre-release. It is recommended for use on POC or demo projects only.
5
+ **Notes:**
6
+
7
+ - This is a pre-release. It is recommended for use on POC or demo projects only.
8
+ - ⚠️ Known issues with using MySQL currently, please use ONLY PostgreSQL or SQLite for your database provider.
9
+ - Templates are applied / extracted on an all or nothing basis – meaning that all the schema, content, and system settings are extracted or applied. We'd love to support more granular operations in the future. (PRs welcome 🙏)
6
10
 
7
11
  ## Usage
8
12
 
13
+ ### Applying a Template
14
+
15
+ **To avoid potential conflicts and bad outcomes, templates can only be applied to a blank instance currently.**
16
+
9
17
  1. Create a Directus instance on [Directus Cloud](https://directus.cloud) or using self-hosted version.
10
18
  2. Login and create a Static Access Token for the admin user.
11
19
  3. Copy the static token and your Directus URL.
12
20
  4. Run the following command on the terminal and follow the prompts.
21
+
13
22
  ```
14
23
  $ npx directus-template-cli apply
15
24
  ```
16
25
 
26
+ You can choose from our templates bundled with the CLI or you can also choose a template from a local directory.
27
+
28
+ ### Extracting a Template
29
+
30
+ The CLI can also extract a template from a Directus instance so that it can be applied to other instances.
31
+
32
+ 1. Make sure you remove any sensitive data from the Directus instance you don't want to include in the template.
33
+ 2. Login and create a Static Access Token for the admin user.
34
+ 3. Copy the static token and your Directus URL.
35
+ 4. Run the following command on the terminal and follow the prompts.
36
+
37
+ ```
38
+ $ npx directus-template-cli extract
39
+ ```
40
+
17
41
  ## License
18
42
 
19
- This template is licensed under the [MIT License](https://opensource.org/licenses/MIT).
43
+ This tool is licensed under the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,4 +1,4 @@
1
- import { Command } from '@oclif/core';
1
+ import { Command } from "@oclif/core";
2
2
  export default class ApplyCommand extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
@@ -4,50 +4,61 @@ const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
5
  const core_2 = require("@oclif/core");
6
6
  const inquirer = tslib_1.__importStar(require("inquirer"));
7
- const read_templates_1 = tslib_1.__importDefault(require("../lib/utils/read-templates"));
8
- const validate_url_1 = tslib_1.__importDefault(require("../lib/utils/validate-url"));
7
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
9
8
  const node_path_1 = tslib_1.__importDefault(require("node:path"));
9
+ const read_templates_1 = require("../lib/utils/read-templates");
10
10
  const api_1 = require("../lib/api");
11
11
  const load_1 = tslib_1.__importDefault(require("../lib/load/"));
12
- const separator = '------------------';
12
+ const auth_1 = require("../lib/utils/auth");
13
+ const separator = "------------------";
13
14
  async function getTemplate() {
14
- const TEMPLATE_DIR = node_path_1.default.join(__dirname, '..', '..', 'templates');
15
- const templates = await (0, read_templates_1.default)(TEMPLATE_DIR);
16
- const templateChoices = templates.map((template) => {
15
+ const TEMPLATE_DIR = node_path_1.default.join(__dirname, "..", "..", "templates");
16
+ const templates = await (0, read_templates_1.readAllTemplates)(TEMPLATE_DIR);
17
+ const officialTemplateChoices = templates.map((template) => {
17
18
  return { name: template.templateName, value: template };
18
19
  });
19
- const template = await inquirer.prompt([{
20
- name: 'template',
21
- message: 'Select a template.',
22
- type: 'list',
23
- choices: templateChoices,
24
- }]);
25
- return template;
26
- }
27
- async function getDirectusUrl() {
28
- const directusUrl = await core_2.ux.prompt('What is your Directus URL?');
29
- // Validate URL
30
- if (!(0, validate_url_1.default)(directusUrl)) {
31
- core_2.ux.warn('Invalid URL');
32
- return getDirectusUrl();
33
- }
34
- return directusUrl;
35
- }
36
- async function getDirectusToken(directusUrl) {
37
- const directusToken = await core_2.ux.prompt('What is your Directus Admin Token?');
38
- // Validate token
39
- try {
40
- await api_1.api.get('/users/me', {
41
- headers: {
42
- Authorization: `Bearer ${directusToken}`,
20
+ const templateType = await inquirer.prompt([
21
+ {
22
+ name: "templateType",
23
+ message: "What type of template would you like to apply?",
24
+ type: "list",
25
+ choices: [
26
+ {
27
+ name: "Official templates",
28
+ value: "official",
29
+ },
30
+ {
31
+ name: "From a local directory",
32
+ value: "local",
33
+ },
34
+ // {
35
+ // name: "From a git repository",
36
+ // value: "git",
37
+ // },
38
+ ],
39
+ },
40
+ ]);
41
+ let template;
42
+ if (templateType.templateType === "official") {
43
+ template = await inquirer.prompt([
44
+ {
45
+ name: "template",
46
+ message: "Select a template.",
47
+ type: "list",
48
+ choices: officialTemplateChoices,
43
49
  },
44
- });
45
- return directusToken;
50
+ ]);
46
51
  }
47
- catch {
48
- core_2.ux.warn('Invalid token');
49
- return getDirectusToken(directusUrl);
52
+ if (templateType.templateType === "local") {
53
+ const localTemplateDir = await core_2.ux.prompt("What is the local template directory?");
54
+ if (!node_fs_1.default.existsSync(localTemplateDir)) {
55
+ core_2.ux.error("Directory does not exist.");
56
+ }
57
+ else {
58
+ template = { template: await (0, read_templates_1.readTemplate)(localTemplateDir) };
59
+ }
50
60
  }
61
+ return template;
51
62
  }
52
63
  class ApplyCommand extends core_1.Command {
53
64
  async run() {
@@ -55,32 +66,32 @@ class ApplyCommand extends core_1.Command {
55
66
  const chosenTemplate = await getTemplate();
56
67
  this.log(`You selected ${chosenTemplate.template.templateName}`);
57
68
  this.log(separator);
58
- const directusUrl = await getDirectusUrl();
69
+ const directusUrl = await (0, auth_1.getDirectusUrl)();
59
70
  api_1.api.setBaseUrl(directusUrl);
60
- const directusToken = await getDirectusToken(directusUrl);
71
+ const directusToken = await (0, auth_1.getDirectusToken)(directusUrl);
61
72
  api_1.api.setAuthToken(directusToken);
62
73
  this.log(separator);
63
74
  // Check if Directus instance is empty, if not, throw error
64
- const { data } = await api_1.api.get('/collections');
65
- // Look for collections that don't start with directus_
66
- const collections = data.data.filter((collection) => {
67
- return !collection.collection.startsWith('directus_');
68
- });
69
- if (collections.length > 0) {
70
- core_2.ux.error('Directus instance is not empty. Please use a blank instance. Copying a template into an existing instance is not supported at this time.');
71
- }
75
+ // const { data }: { data: any } = await api.get("/collections");
76
+ // // Look for collections that don't start with directus_
77
+ // const collections = data.data.filter((collection: any) => {
78
+ // return !collection.collection.startsWith("directus_");
79
+ // });
80
+ // if (collections.length > 0) {
81
+ // ux.error(
82
+ // "Directus instance is not empty. Please use a blank instance. Copying a template into an existing instance is not supported at this time."
83
+ // );
84
+ // }
72
85
  // Run load script
73
86
  core_2.ux.action.start(`Applying template - ${chosenTemplate.template.templateName}`);
74
87
  await (0, load_1.default)(chosenTemplate.template.directoryPath, this);
75
88
  core_2.ux.action.stop();
76
89
  this.log(separator);
77
- this.log('Template applied successfully.');
78
- this.exit;
90
+ this.log("Template applied successfully.");
91
+ this.exit(0);
79
92
  }
80
93
  }
81
94
  exports.default = ApplyCommand;
82
- ApplyCommand.description = 'Apply a template to a blank Directus instance.';
83
- ApplyCommand.examples = [
84
- '$ directus-template-cli apply',
85
- ];
95
+ ApplyCommand.description = "Apply a template to a blank Directus instance.";
96
+ ApplyCommand.examples = ["$ directus-template-cli apply"];
86
97
  ApplyCommand.flags = {};
@@ -0,0 +1,7 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class ExtractCommand extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {};
6
+ run(): Promise<void>;
7
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const core_2 = require("@oclif/core");
6
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
7
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
8
+ const api_1 = require("../lib/api");
9
+ const extract_1 = tslib_1.__importDefault(require("../lib/extract/"));
10
+ const auth_1 = require("../lib/utils/auth");
11
+ const template_defaults_1 = require("../lib/utils/template-defaults");
12
+ const separator = "------------------";
13
+ class ExtractCommand extends core_1.Command {
14
+ async run() {
15
+ const { flags } = await this.parse(ExtractCommand);
16
+ const templateName = await core_2.ux.prompt("What is the name of the template?.");
17
+ const directory = await core_2.ux.prompt("What directory would you like to extract the template to? If it doesn't exist, it will be created.");
18
+ this.log(`You selected ${directory}`);
19
+ try {
20
+ // Check if directory exists, if not, then create it.
21
+ if (!node_fs_1.default.existsSync(directory)) {
22
+ node_fs_1.default.mkdirSync(directory, { recursive: true });
23
+ }
24
+ // Create package.json and README.md
25
+ const packageJSONContent = (0, template_defaults_1.generatePackageJsonContent)(templateName);
26
+ const readmeContent = (0, template_defaults_1.generateReadmeContent)(templateName);
27
+ // Write the content to the specified directory
28
+ const packageJSONPath = node_path_1.default.join(directory, "package.json");
29
+ const readmePath = node_path_1.default.join(directory, "README.md");
30
+ node_fs_1.default.writeFileSync(packageJSONPath, packageJSONContent);
31
+ node_fs_1.default.writeFileSync(readmePath, readmeContent);
32
+ }
33
+ catch (error) {
34
+ console.error(`Failed to create directory or write files: ${error.message}`);
35
+ }
36
+ this.log(separator);
37
+ const directusUrl = await (0, auth_1.getDirectusUrl)();
38
+ api_1.api.setBaseUrl(directusUrl);
39
+ const directusToken = await (0, auth_1.getDirectusToken)(directusUrl);
40
+ api_1.api.setAuthToken(directusToken);
41
+ this.log(separator);
42
+ // Run the extract script
43
+ core_2.ux.action.start(`Extracting template - from ${directusUrl} to ${directory}`);
44
+ await (0, extract_1.default)(directory, this);
45
+ core_2.ux.action.stop();
46
+ this.log(separator);
47
+ this.log("Template extracted successfully.");
48
+ this.exit(0);
49
+ }
50
+ }
51
+ exports.default = ExtractCommand;
52
+ ExtractCommand.description = "Extract a template from a Directus instance.";
53
+ ExtractCommand.examples = ["$ directus-template-cli extract"];
54
+ ExtractCommand.flags = {};
@@ -0,0 +1,3 @@
1
+ export declare function getAssetList(): Promise<any>;
2
+ export declare function downloadFile(file: any, dir: string): Promise<unknown>;
3
+ export declare function downloadAllFiles(dir: string): Promise<void>;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.downloadAllFiles = exports.downloadFile = exports.getAssetList = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
6
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
7
+ const api_1 = require("../api");
8
+ async function getAssetList() {
9
+ const { data } = await api_1.api.get("/files", {
10
+ params: {
11
+ limit: "-1",
12
+ },
13
+ });
14
+ return data.data;
15
+ }
16
+ exports.getAssetList = getAssetList;
17
+ async function downloadFile(file, dir) {
18
+ const response = await api_1.api.get(`assets/${file.id}`, {
19
+ responseType: "stream",
20
+ });
21
+ // Create assets folder if it doesn't exist
22
+ const fullPath = node_path_1.default.join(dir, "assets");
23
+ if (node_path_1.default && !node_fs_1.default.existsSync(fullPath)) {
24
+ node_fs_1.default.mkdirSync(fullPath, { recursive: true });
25
+ }
26
+ const writePath = node_path_1.default.resolve(dir, "assets", file.filename_disk);
27
+ const writer = node_fs_1.default.createWriteStream(writePath);
28
+ response.data.pipe(writer);
29
+ return new Promise((resolve, reject) => {
30
+ writer.on("finish", () => {
31
+ console.log(`Wrote ${file.filename_disk}`);
32
+ resolve(null);
33
+ });
34
+ writer.on("error", reject);
35
+ });
36
+ }
37
+ exports.downloadFile = downloadFile;
38
+ async function downloadAllFiles(dir) {
39
+ const fileList = await getAssetList();
40
+ for (const file of fileList) {
41
+ try {
42
+ await downloadFile(file, dir);
43
+ }
44
+ catch (error) {
45
+ console.log(`Error downloading ${file.filename_disk}`, error);
46
+ }
47
+ }
48
+ }
49
+ exports.downloadAllFiles = downloadAllFiles;
@@ -0,0 +1,3 @@
1
+ export declare function getCollections(): Promise<any>;
2
+ export declare function getDataFromCollection(collection: string, dir: string): Promise<void>;
3
+ export declare function extractContent(dir: string): Promise<void>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractContent = exports.getDataFromCollection = exports.getCollections = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const api_1 = require("../api");
6
+ const write_to_file_1 = tslib_1.__importDefault(require("../utils/write-to-file"));
7
+ async function getCollections() {
8
+ const { data } = await api_1.api.get("/collections");
9
+ const collections = data.data
10
+ .filter((item) => !item.collection.startsWith("directus_", 0))
11
+ .filter((item) => item.schema != null)
12
+ .map((i) => i.collection);
13
+ return collections;
14
+ }
15
+ exports.getCollections = getCollections;
16
+ async function getDataFromCollection(collection, dir) {
17
+ try {
18
+ const { data } = await api_1.api.get(`items/${collection}`); // ADD limit = -1
19
+ (0, write_to_file_1.default)(`${collection}`, data.data, `${dir}/content/`);
20
+ }
21
+ catch {
22
+ console.log(`error getting items from ${collection}`);
23
+ // Errors are thrown for 'folder' collections
24
+ }
25
+ }
26
+ exports.getDataFromCollection = getDataFromCollection;
27
+ async function extractContent(dir) {
28
+ const collections = await getCollections();
29
+ for (const collection of collections) {
30
+ await getDataFromCollection(collection, dir);
31
+ }
32
+ }
33
+ exports.extractContent = extractContent;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * [default query an endpoint and write the result to file]
3
+ */
4
+ export default function extractFromEndpoint(path: string, dir: string): Promise<void>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const api_1 = require("../api");
5
+ const write_to_file_1 = tslib_1.__importDefault(require("../utils/write-to-file"));
6
+ /**
7
+ * [default query an endpoint and write the result to file]
8
+ */
9
+ async function extractFromEndpoint(path, dir) {
10
+ try {
11
+ const { data } = await api_1.api.get(`/${path}`, {
12
+ params: {
13
+ limit: "-1",
14
+ },
15
+ });
16
+ // Use the dynamic dir parameter
17
+ await (0, write_to_file_1.default)(`${path}`, data.data, dir);
18
+ }
19
+ catch (error) {
20
+ console.log(`Error querying endpoint ${path}:`, error);
21
+ }
22
+ }
23
+ exports.default = extractFromEndpoint;
@@ -0,0 +1 @@
1
+ export default function extractSchema(dir: string): Promise<void>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
5
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
6
+ const api_1 = require("../api");
7
+ const write_to_file_1 = tslib_1.__importDefault(require("../utils/write-to-file"));
8
+ async function extractSchema(dir) {
9
+ const schemaDir = node_path_1.default.join(dir, "schema");
10
+ // Check if directory for schema exists, if not, then create it.
11
+ if (!node_fs_1.default.existsSync(schemaDir)) {
12
+ console.log(`Attempting to create directory at: ${schemaDir}`);
13
+ node_fs_1.default.mkdirSync(schemaDir, { recursive: true });
14
+ }
15
+ // Get the schema
16
+ try {
17
+ const { data } = await api_1.api.get("/schema/snapshot", {
18
+ params: {
19
+ limit: "-1",
20
+ },
21
+ });
22
+ // Write the schema to the specified directory
23
+ await (0, write_to_file_1.default)("schema/snapshot", data.data, dir);
24
+ }
25
+ catch (error) {
26
+ console.log("Error fetching schema snapshot:", error);
27
+ }
28
+ }
29
+ exports.default = extractSchema;
@@ -0,0 +1 @@
1
+ export default function extract(dir: string, cli: any): Promise<{}>;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
5
+ const extract_assets_1 = require("./extract-assets");
6
+ const extract_schema_1 = tslib_1.__importDefault(require("./extract-schema"));
7
+ const extract_from_endpoint_1 = tslib_1.__importDefault(require("./extract-from-endpoint"));
8
+ const public_permissions_1 = tslib_1.__importDefault(require("./public-permissions"));
9
+ const extract_content_1 = require("./extract-content");
10
+ const endpoints = [
11
+ "folders",
12
+ "operations",
13
+ "fields",
14
+ "users",
15
+ "roles",
16
+ "files",
17
+ "permissions",
18
+ "collections",
19
+ "flows",
20
+ "dashboards",
21
+ "panels",
22
+ "presets",
23
+ "settings",
24
+ ];
25
+ async function extract(dir, cli) {
26
+ // Get the destination directory for the actual files
27
+ const destination = dir + "/src";
28
+ // Check if directory exists, if not, then create it.
29
+ if (!node_fs_1.default.existsSync(destination)) {
30
+ console.log(`Attempting to create directory at: ${destination}`);
31
+ node_fs_1.default.mkdirSync(destination, { recursive: true });
32
+ }
33
+ // Extract the schema
34
+ await (0, extract_schema_1.default)(destination);
35
+ // Iterate through the endpoints
36
+ for (const endpoint of endpoints) {
37
+ await (0, extract_from_endpoint_1.default)(endpoint, destination);
38
+ }
39
+ // Extract public permissions
40
+ await (0, public_permissions_1.default)(destination);
41
+ // Extract content
42
+ await (0, extract_content_1.extractContent)(destination);
43
+ // Extract assets
44
+ await (0, extract_assets_1.downloadAllFiles)(destination);
45
+ return {};
46
+ }
47
+ exports.default = extract;
@@ -0,0 +1 @@
1
+ export default function extractPublicPermissions(dir: string): Promise<void>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const api_1 = require("../api");
5
+ const write_to_file_1 = tslib_1.__importDefault(require("../utils/write-to-file"));
6
+ async function extractPublicPermissions(dir) {
7
+ try {
8
+ const { data } = await api_1.api.get("permissions", {
9
+ params: {
10
+ limit: "-1",
11
+ "filter[role][_null]": true,
12
+ },
13
+ });
14
+ // Write the public permissions to the specified directory
15
+ await (0, write_to_file_1.default)("public-permissions", data.data, dir);
16
+ }
17
+ catch (error) {
18
+ console.log("Error fetching public permissions:", error);
19
+ }
20
+ }
21
+ exports.default = extractPublicPermissions;
@@ -7,43 +7,46 @@ const load_schema_1 = tslib_1.__importDefault(require("./load-schema"));
7
7
  const load_roles_1 = tslib_1.__importDefault(require("./load-roles"));
8
8
  const load_dashboards_1 = tslib_1.__importDefault(require("./load-dashboards"));
9
9
  const load_files_1 = tslib_1.__importDefault(require("./load-files"));
10
+ const load_folders_1 = tslib_1.__importDefault(require("./load-folders"));
10
11
  const load_users_1 = tslib_1.__importDefault(require("./load-users"));
11
12
  const load_flows_1 = tslib_1.__importDefault(require("./load-flows"));
12
13
  const load_operations_1 = tslib_1.__importDefault(require("./load-operations"));
13
14
  const load_data_1 = tslib_1.__importDefault(require("./load-data"));
14
15
  const load_presets_1 = tslib_1.__importDefault(require("./load-presets"));
15
16
  const load_settings_1 = tslib_1.__importDefault(require("./load-settings"));
16
- const load_public_permissions_1 = tslib_1.__importDefault(require("./load-public-permissions"));
17
+ const load_public_permissions_1 = require("./load-public-permissions");
17
18
  async function apply(dir, cli) {
18
19
  // Get the source directory for the actual files
19
- const source = dir + '/src';
20
+ const source = dir + "/src";
20
21
  // Load the template files into the destination
21
- await (0, load_schema_1.default)(source + '/schema');
22
- cli.log('Loaded Schema');
23
- await (0, load_roles_1.default)((0, read_file_1.default)('roles', source));
24
- cli.log('Loaded Roles');
25
- await (0, load_to_destination_1.default)('folders', (0, read_file_1.default)('folders', source));
26
- cli.log('Loaded Folders');
27
- await (0, load_dashboards_1.default)((0, read_file_1.default)('dashboards', source));
28
- cli.log('Loaded Dashboards');
29
- await (0, load_to_destination_1.default)('panels', (0, read_file_1.default)('panels', source)); // Comes after dashboards
30
- cli.log('Loaded Panels');
31
- await (0, load_files_1.default)((0, read_file_1.default)('files', source), source); // Comes after folders
32
- cli.log('Loaded Files');
33
- await (0, load_users_1.default)((0, read_file_1.default)('users', source)); // Comes after roles, files
34
- cli.log('Loaded Users');
35
- await (0, load_flows_1.default)((0, read_file_1.default)('flows', source));
36
- cli.log('Loaded Flows');
37
- await (0, load_operations_1.default)((0, read_file_1.default)('operations', source)); // Comes after flows
38
- cli.log('Loaded Operations');
39
- await (0, load_data_1.default)((0, read_file_1.default)('collections', source), source);
40
- cli.log('Loaded Data');
41
- await (0, load_presets_1.default)((0, read_file_1.default)('presets', source));
42
- cli.log('Loaded Presets');
43
- await (0, load_settings_1.default)((0, read_file_1.default)('settings', source));
44
- cli.log('Loaded Settings');
45
- await (0, load_public_permissions_1.default)((0, read_file_1.default)('public-permissions', source));
46
- cli.log('Loaded Public Permissions');
22
+ await (0, load_schema_1.default)(source + "/schema");
23
+ cli.log("Loaded Schema");
24
+ await (0, load_roles_1.default)((0, read_file_1.default)("roles", source));
25
+ cli.log("Loaded Roles");
26
+ await (0, load_files_1.default)((0, read_file_1.default)("files", source), source); // Comes after folders
27
+ cli.log("Loaded Files");
28
+ await (0, load_users_1.default)((0, read_file_1.default)("users", source)); // Comes after roles, files
29
+ cli.log("Loaded Users");
30
+ await (0, load_folders_1.default)(source);
31
+ cli.log("Loaded Folders");
32
+ await (0, load_dashboards_1.default)((0, read_file_1.default)("dashboards", source));
33
+ cli.log("Loaded Dashboards");
34
+ await (0, load_to_destination_1.default)("panels", (0, read_file_1.default)("panels", source)); // Comes after dashboards
35
+ cli.log("Loaded Panels");
36
+ await (0, load_flows_1.default)((0, read_file_1.default)("flows", source));
37
+ cli.log("Loaded Flows");
38
+ await (0, load_operations_1.default)((0, read_file_1.default)("operations", source)); // Comes after flows
39
+ cli.log("Loaded Operations");
40
+ await (0, load_data_1.default)((0, read_file_1.default)("collections", source), source);
41
+ cli.log("Loaded Data");
42
+ await (0, load_presets_1.default)((0, read_file_1.default)("presets", source));
43
+ cli.log("Loaded Presets");
44
+ await (0, load_settings_1.default)((0, read_file_1.default)("settings", source));
45
+ cli.log("Loaded Settings");
46
+ await (0, load_public_permissions_1.loadPublicPermissions)((0, read_file_1.default)("public-permissions", source));
47
+ cli.log("Loaded Public Permissions");
48
+ await (0, load_public_permissions_1.loadPermissions)((0, read_file_1.default)("permissions", source));
49
+ cli.log("Loaded Permissions");
47
50
  return {};
48
51
  }
49
52
  exports.default = apply;
@@ -5,12 +5,20 @@ const api_1 = require("../api");
5
5
  const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
6
6
  async function loadFolders(dir) {
7
7
  try {
8
- const folders = await (0, read_file_1.default)('folders', dir);
9
- const { data } = await api_1.api.post('/folders', folders);
10
- console.log('Folder creation', data);
8
+ const folders = await (0, read_file_1.default)("folders", dir);
9
+ const folderSkeleton = folders.map((folder) => {
10
+ return { id: folder.id, name: folder.name };
11
+ });
12
+ // Create the folders
13
+ const { data } = await api_1.api.post("/folders", folderSkeleton);
14
+ // Loop through the folders and update them with relationships
15
+ folders.forEach(async (folder) => {
16
+ const { id, ...rest } = folder;
17
+ await api_1.api.patch(`/folders/${id}`, rest);
18
+ });
11
19
  }
12
20
  catch (error) {
13
- console.log('Error loading Folders', error.response.data.errors);
21
+ console.log("Error loading Folders", error.response.data.errors);
14
22
  }
15
23
  }
16
24
  exports.default = loadFolders;
@@ -2,16 +2,27 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const api_1 = require("../api");
4
4
  exports.default = async (presets) => {
5
- const cleanPresets = presets.map(preset => {
5
+ await deleteAllPresets();
6
+ const cleanPresets = presets.map((preset) => {
6
7
  preset.user = null;
7
8
  return preset;
8
9
  });
9
- for (const preset of cleanPresets) {
10
- try {
11
- await api_1.api.post('presets', preset);
12
- }
13
- catch (error) {
14
- console.log('Error uploading preset', error.response.data.errors);
15
- }
10
+ try {
11
+ await api_1.api.post("presets", cleanPresets);
12
+ }
13
+ catch (error) {
14
+ console.log("Error uploading preset", error.response.data.errors);
15
+ }
16
+ };
17
+ const deleteAllPresets = async () => {
18
+ try {
19
+ const { data: presets } = await api_1.api.get("presets");
20
+ const ids = presets.data.map((preset) => preset.id);
21
+ await api_1.api.delete("presets", {
22
+ data: ids,
23
+ });
24
+ }
25
+ catch (error) {
26
+ console.log("Error removing existing presets", error.response.data.errors);
16
27
  }
17
28
  };
@@ -1 +1,2 @@
1
- export default function loadPublicPermissions(roles: any): Promise<void>;
1
+ export declare function loadPublicPermissions(roles: any): Promise<void>;
2
+ export declare function loadPermissions(roles: any): Promise<void>;