directus-template-cli 0.6.0-beta.2 → 0.7.0-beta.10

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 (114) hide show
  1. package/README.md +0 -14
  2. package/bin/dev.js +6 -0
  3. package/bin/run.js +5 -0
  4. package/dist/commands/apply.d.ts +17 -17
  5. package/dist/commands/apply.js +166 -174
  6. package/dist/commands/base.d.ts +15 -0
  7. package/dist/commands/base.js +45 -0
  8. package/dist/commands/extract.d.ts +16 -9
  9. package/dist/commands/extract.js +81 -100
  10. package/dist/commands/init.d.ts +42 -0
  11. package/dist/commands/init.js +241 -0
  12. package/dist/flags/common.d.ts +8 -7
  13. package/dist/flags/common.js +13 -11
  14. package/dist/index.js +1 -5
  15. package/dist/lib/constants.d.ts +18 -0
  16. package/dist/lib/constants.js +25 -6
  17. package/dist/lib/extract/extract-access.js +11 -15
  18. package/dist/lib/extract/extract-assets.js +20 -25
  19. package/dist/lib/extract/extract-collections.js +12 -16
  20. package/dist/lib/extract/extract-content.d.ts +1 -1
  21. package/dist/lib/extract/extract-content.js +17 -26
  22. package/dist/lib/extract/extract-dashboards.js +22 -28
  23. package/dist/lib/extract/extract-extensions.js +12 -16
  24. package/dist/lib/extract/extract-fields.js +12 -16
  25. package/dist/lib/extract/extract-files.js +15 -19
  26. package/dist/lib/extract/extract-flows.js +22 -28
  27. package/dist/lib/extract/extract-folders.js +15 -19
  28. package/dist/lib/extract/extract-permissions.js +12 -16
  29. package/dist/lib/extract/extract-policies.js +12 -16
  30. package/dist/lib/extract/extract-presets.js +12 -16
  31. package/dist/lib/extract/extract-relations.js +14 -18
  32. package/dist/lib/extract/extract-roles.js +15 -19
  33. package/dist/lib/extract/extract-schema.js +17 -21
  34. package/dist/lib/extract/extract-settings.js +12 -16
  35. package/dist/lib/extract/extract-translations.js +12 -16
  36. package/dist/lib/extract/extract-users.js +15 -19
  37. package/dist/lib/extract/index.d.ts +1 -6
  38. package/dist/lib/extract/index.js +47 -58
  39. package/dist/lib/init/config.d.ts +3 -0
  40. package/dist/lib/init/config.js +12 -0
  41. package/dist/lib/init/index.d.ts +10 -0
  42. package/dist/lib/init/index.js +192 -0
  43. package/dist/lib/init/types.d.ts +30 -0
  44. package/dist/lib/init/types.js +1 -0
  45. package/dist/lib/load/apply-flags.js +17 -23
  46. package/dist/lib/load/index.d.ts +1 -12
  47. package/dist/lib/load/index.js +40 -44
  48. package/dist/lib/load/load-access.js +15 -20
  49. package/dist/lib/load/load-collections.d.ts +2 -0
  50. package/dist/lib/load/load-collections.js +29 -32
  51. package/dist/lib/load/load-dashboards.js +19 -25
  52. package/dist/lib/load/load-data.js +43 -49
  53. package/dist/lib/load/load-extensions.js +30 -38
  54. package/dist/lib/load/load-files.js +20 -24
  55. package/dist/lib/load/load-flows.js +23 -29
  56. package/dist/lib/load/load-folders.js +16 -20
  57. package/dist/lib/load/load-permissions.js +13 -17
  58. package/dist/lib/load/load-policies.js +14 -18
  59. package/dist/lib/load/load-presets.js +14 -18
  60. package/dist/lib/load/load-relations.d.ts +2 -0
  61. package/dist/lib/load/load-relations.js +16 -18
  62. package/dist/lib/load/load-roles.js +19 -23
  63. package/dist/lib/load/load-settings.js +18 -21
  64. package/dist/lib/load/load-translations.js +14 -18
  65. package/dist/lib/load/load-users.js +21 -25
  66. package/dist/lib/load/update-required-fields.js +13 -17
  67. package/dist/lib/sdk.d.ts +1 -2
  68. package/dist/lib/sdk.js +27 -27
  69. package/dist/lib/types/extension.js +1 -2
  70. package/dist/lib/types.d.ts +18 -0
  71. package/dist/lib/types.js +1 -0
  72. package/dist/lib/utils/animated-bunny.d.ts +2 -0
  73. package/dist/lib/utils/animated-bunny.js +62 -0
  74. package/dist/lib/utils/auth.d.ts +8 -6
  75. package/dist/lib/utils/auth.js +48 -39
  76. package/dist/lib/utils/catch-error.js +8 -11
  77. package/dist/lib/utils/check-template.js +4 -8
  78. package/dist/lib/utils/chunk-array.js +1 -5
  79. package/dist/lib/utils/ensure-dir.d.ts +2 -0
  80. package/dist/lib/utils/ensure-dir.js +11 -0
  81. package/dist/lib/utils/filter-fields.js +1 -4
  82. package/dist/lib/utils/get-role-ids.d.ts +1 -1
  83. package/dist/lib/utils/get-role-ids.js +7 -12
  84. package/dist/lib/utils/get-template.js +33 -36
  85. package/dist/lib/utils/logger.js +11 -13
  86. package/dist/lib/utils/open-url.js +5 -8
  87. package/dist/lib/utils/parse-github-url.d.ts +19 -0
  88. package/dist/lib/utils/parse-github-url.js +89 -0
  89. package/dist/lib/utils/path.js +6 -10
  90. package/dist/lib/utils/protected-domains.js +1 -4
  91. package/dist/lib/utils/read-file.js +8 -12
  92. package/dist/lib/utils/read-templates.js +9 -15
  93. package/dist/lib/utils/sanitize-flags.d.ts +3 -0
  94. package/dist/lib/utils/sanitize-flags.js +4 -0
  95. package/dist/lib/utils/system-fields.js +19 -22
  96. package/dist/lib/utils/template-config.d.ts +16 -0
  97. package/dist/lib/utils/template-config.js +34 -0
  98. package/dist/lib/utils/template-defaults.d.ts +1 -1
  99. package/dist/lib/utils/template-defaults.js +5 -14
  100. package/dist/lib/utils/transform-github-url.js +1 -5
  101. package/dist/lib/utils/validate-url.js +3 -6
  102. package/dist/lib/utils/wait.d.ts +7 -0
  103. package/dist/lib/utils/wait.js +9 -0
  104. package/dist/lib/utils/write-to-file.js +8 -11
  105. package/dist/services/docker.d.ts +23 -0
  106. package/dist/services/docker.js +187 -0
  107. package/dist/services/github.d.ts +18 -0
  108. package/dist/services/github.js +88 -0
  109. package/dist/services/posthog.d.ts +37 -0
  110. package/dist/services/posthog.js +104 -0
  111. package/oclif.manifest.json +102 -23
  112. package/package.json +46 -29
  113. package/bin/dev +0 -17
  114. package/bin/run +0 -5
@@ -0,0 +1,89 @@
1
+ import { DEFAULT_BRANCH, DEFAULT_REPO } from '../constants.js';
2
+ /**
3
+ * Clean and normalize a GitHub URL
4
+ * Handles various formats:
5
+ * - Full URLs with .git
6
+ * - URLs with query parameters
7
+ * - URLs with hash fragments
8
+ * - URLs with branches/refs
9
+ * - Repository paths
10
+ * @param url The URL or path to clean
11
+ * @returns Cleaned URL without .git, queries, or hashes
12
+ */
13
+ function cleanGitHubUrl(url) {
14
+ try {
15
+ // If it's not a URL, return as is (might be a path)
16
+ if (!url.includes('://')) {
17
+ return url.replace(/\.git$/, '');
18
+ }
19
+ // Parse the URL
20
+ const parsed = new URL(url);
21
+ // Remove .git suffix from pathname
22
+ parsed.pathname = parsed.pathname.replace(/\.git$/, '');
23
+ // Remove search params and hash
24
+ parsed.search = '';
25
+ parsed.hash = '';
26
+ return parsed.toString();
27
+ }
28
+ catch (error) {
29
+ // If URL parsing fails, just remove .git suffix
30
+ return url.replace(/\.git$/, '');
31
+ }
32
+ }
33
+ /**
34
+ * Parse a GitHub URL or path into its components
35
+ * @param url The URL or path to parse
36
+ * @returns The parsed components
37
+ */
38
+ export function parseGitHubUrl(url) {
39
+ if (!url) {
40
+ throw new Error('URL is required');
41
+ }
42
+ // Clean the URL first
43
+ const cleanedUrl = cleanGitHubUrl(url);
44
+ // Handle full GitHub URLs
45
+ if (cleanedUrl.includes('github.com')) {
46
+ try {
47
+ const parsed = new URL(cleanedUrl);
48
+ const parts = parsed.pathname.split('/').filter(Boolean);
49
+ if (parts.length < 2) {
50
+ throw new Error('Invalid GitHub URL format');
51
+ }
52
+ const [owner, repo, ...rest] = parts;
53
+ const path = rest.length > 0 ? rest.join('/') : undefined;
54
+ const ref = parsed.searchParams.get('ref') || DEFAULT_BRANCH;
55
+ return { owner, repo, path, ref };
56
+ }
57
+ catch (error) {
58
+ throw new Error(`Invalid GitHub URL: ${url}`);
59
+ }
60
+ }
61
+ // Handle repository paths (owner/repo format)
62
+ const parts = cleanedUrl.split('/').filter(Boolean);
63
+ if (parts.length >= 2) {
64
+ const [owner, repo, ...rest] = parts;
65
+ const path = rest.length > 0 ? rest.join('/') : undefined;
66
+ return { owner, repo, path, ref: DEFAULT_BRANCH };
67
+ }
68
+ // Handle simple template names using DEFAULT_REPO
69
+ return {
70
+ ...DEFAULT_REPO,
71
+ path: cleanedUrl // The template name becomes the subpath
72
+ };
73
+ }
74
+ /**
75
+ * Creates a giget-compatible string from GitHub URL parts
76
+ * @param parts The parsed GitHub URL parts
77
+ * @returns A string in the format 'gh:owner/repo#ref[/path]'
78
+ */
79
+ export function createGigetString(parts) {
80
+ // For the default repo case with a template name
81
+ if (parts.owner === DEFAULT_REPO.owner && parts.repo === DEFAULT_REPO.repo) {
82
+ return `gh:${parts.owner}/${parts.repo}/${parts.path}#${DEFAULT_REPO.ref}`;
83
+ }
84
+ // For other GitHub URLs
85
+ const base = `gh:${parts.owner}/${parts.repo}`;
86
+ const path = parts.path ? `/${parts.path}` : '';
87
+ const ref = parts.ref ? `#${parts.ref}` : '';
88
+ return `${base}${path}${ref}`;
89
+ }
@@ -1,20 +1,16 @@
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 node_process_1 = require("node:process");
1
+ import fs from 'node:fs';
2
+ import path from 'pathe';
3
+ import { cwd } from 'node:process';
7
4
  /**
8
5
  * Resolves a given path to an absolute path and checks if it exists.
9
6
  * @param inputPath The path to resolve.
10
7
  * @param checkExistence Whether to check if the resolved path exists.
11
8
  * @returns The resolved absolute path if it exists, or null if it doesn't.
12
9
  */
13
- function resolvePathAndCheckExistence(inputPath, checkExistence = true) {
14
- const resolvedPath = node_path_1.default.isAbsolute(inputPath) ? inputPath : node_path_1.default.resolve((0, node_process_1.cwd)(), inputPath);
15
- if (!checkExistence || node_fs_1.default.existsSync(resolvedPath)) {
10
+ export default function resolvePathAndCheckExistence(inputPath, checkExistence = true) {
11
+ const resolvedPath = path.isAbsolute(inputPath) ? inputPath : path.resolve(cwd(), inputPath);
12
+ if (!checkExistence || fs.existsSync(resolvedPath)) {
16
13
  return resolvedPath;
17
14
  }
18
15
  return null;
19
16
  }
20
- exports.default = resolvePathAndCheckExistence;
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.protectedDomains = void 0;
4
- exports.protectedDomains = [
1
+ export const protectedDomains = [
5
2
  'directus.pizza',
6
3
  ];
@@ -1,16 +1,12 @@
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 catch_error_1 = tslib_1.__importDefault(require("./catch-error"));
7
- function readFile(file, dir) {
8
- const filePath = node_path_1.default.join(dir, `${file}.json`); // Use path.join for proper path resolution
9
- if (!node_fs_1.default.existsSync(filePath)) {
10
- (0, catch_error_1.default)(`File not found: ${filePath}`);
1
+ import fs from 'node:fs';
2
+ import path from 'pathe';
3
+ import catchError from './catch-error.js';
4
+ export default function readFile(file, dir) {
5
+ const filePath = path.join(dir, `${file}.json`); // Use path.join for proper path resolution
6
+ if (!fs.existsSync(filePath)) {
7
+ catchError(`File not found: ${filePath}`);
11
8
  }
12
- const fileContents = node_fs_1.default.readFileSync(filePath, 'utf8');
9
+ const fileContents = fs.readFileSync(filePath, 'utf8');
13
10
  const obj = JSON.parse(fileContents);
14
11
  return obj;
15
12
  }
16
- exports.default = readFile;
@@ -1,13 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readAllTemplates = exports.readTemplate = 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
- async function readTemplate(directoryPath) {
8
- const packageFilePath = node_path_1.default.join(directoryPath, 'package.json');
1
+ import fs from 'node:fs';
2
+ import path from 'pathe';
3
+ export async function readTemplate(directoryPath) {
4
+ const packageFilePath = path.join(directoryPath, 'package.json');
9
5
  try {
10
- const packageData = await node_fs_1.default.promises.readFile(packageFilePath, 'utf8');
6
+ const packageData = await fs.promises.readFile(packageFilePath, 'utf8');
11
7
  const packageJson = JSON.parse(packageData);
12
8
  if (packageJson.templateName) {
13
9
  return {
@@ -24,13 +20,12 @@ async function readTemplate(directoryPath) {
24
20
  return null;
25
21
  }
26
22
  }
27
- exports.readTemplate = readTemplate;
28
- async function readAllTemplates(directoryPath) {
23
+ export async function readAllTemplates(directoryPath) {
29
24
  const templates = [];
30
- const files = await node_fs_1.default.promises.readdir(directoryPath);
25
+ const files = await fs.promises.readdir(directoryPath);
31
26
  for (const file of files) {
32
- const filePath = node_path_1.default.join(directoryPath, file);
33
- const stats = await node_fs_1.default.promises.stat(filePath);
27
+ const filePath = path.join(directoryPath, file);
28
+ const stats = await fs.promises.stat(filePath);
34
29
  if (stats.isDirectory()) {
35
30
  const template = await readTemplate(filePath);
36
31
  if (template) {
@@ -40,4 +35,3 @@ async function readAllTemplates(directoryPath) {
40
35
  }
41
36
  return templates;
42
37
  }
43
- exports.readAllTemplates = readAllTemplates;
@@ -0,0 +1,3 @@
1
+ export declare const sanitizeFlags: (flags: Record<string, unknown>) => {
2
+ [k: string]: unknown;
3
+ };
@@ -0,0 +1,4 @@
1
+ const SENSITIVE_FLAGS = ['userEmail', 'userPassword', 'directusToken'];
2
+ export const sanitizeFlags = (flags) => {
3
+ return Object.fromEntries(Object.entries(flags).filter(([key]) => !SENSITIVE_FLAGS.includes(key)));
4
+ };
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.systemFields = exports.directusSettingsFields = exports.directusPanelFields = exports.directusDashboardFields = exports.directusOperationFields = exports.directusFlowFields = exports.directusFolderFields = exports.directusFileFields = exports.directusRoleFields = exports.directusUserFields = void 0;
4
- exports.directusUserFields = [
1
+ export const directusUserFields = [
5
2
  'id',
6
3
  'status',
7
4
  'first_name',
@@ -25,7 +22,7 @@ exports.directusUserFields = [
25
22
  'tags',
26
23
  'email_notifications',
27
24
  ];
28
- exports.directusRoleFields = [
25
+ export const directusRoleFields = [
29
26
  'id',
30
27
  'name',
31
28
  'description',
@@ -36,7 +33,7 @@ exports.directusRoleFields = [
36
33
  'app_access',
37
34
  'admin_access',
38
35
  ];
39
- exports.directusFileFields = [
36
+ export const directusFileFields = [
40
37
  'id',
41
38
  'storage',
42
39
  'filename_disk',
@@ -59,12 +56,12 @@ exports.directusFileFields = [
59
56
  'tags',
60
57
  'metadata',
61
58
  ];
62
- exports.directusFolderFields = [
59
+ export const directusFolderFields = [
63
60
  'id',
64
61
  'name',
65
62
  'parent',
66
63
  ];
67
- exports.directusFlowFields = [
64
+ export const directusFlowFields = [
68
65
  'id',
69
66
  'name',
70
67
  'icon',
@@ -78,7 +75,7 @@ exports.directusFlowFields = [
78
75
  'date_created',
79
76
  'user_created',
80
77
  ];
81
- exports.directusOperationFields = [
78
+ export const directusOperationFields = [
82
79
  'id',
83
80
  'name',
84
81
  'key',
@@ -92,7 +89,7 @@ exports.directusOperationFields = [
92
89
  'date_created',
93
90
  'user_created',
94
91
  ];
95
- exports.directusDashboardFields = [
92
+ export const directusDashboardFields = [
96
93
  'id',
97
94
  'name',
98
95
  'icon',
@@ -101,7 +98,7 @@ exports.directusDashboardFields = [
101
98
  'user_created',
102
99
  'color',
103
100
  ];
104
- exports.directusPanelFields = [
101
+ export const directusPanelFields = [
105
102
  'id',
106
103
  'dashboard',
107
104
  'name',
@@ -118,7 +115,7 @@ exports.directusPanelFields = [
118
115
  'date_created',
119
116
  'user_created',
120
117
  ];
121
- exports.directusSettingsFields = [
118
+ export const directusSettingsFields = [
122
119
  'id',
123
120
  'project_name',
124
121
  'project_url',
@@ -146,14 +143,14 @@ exports.directusSettingsFields = [
146
143
  'default_theme_dark',
147
144
  'theme_dark_overrides',
148
145
  ];
149
- exports.systemFields = {
150
- directus_dashboards: exports.directusDashboardFields,
151
- directus_files: exports.directusFileFields,
152
- directus_flows: exports.directusFlowFields,
153
- directus_folders: exports.directusFolderFields,
154
- directus_operations: exports.directusOperationFields,
155
- directus_panels: exports.directusPanelFields,
156
- directus_roles: exports.directusRoleFields,
157
- directus_settings: exports.directusSettingsFields,
158
- directus_users: exports.directusUserFields,
146
+ export const systemFields = {
147
+ directus_dashboards: directusDashboardFields,
148
+ directus_files: directusFileFields,
149
+ directus_flows: directusFlowFields,
150
+ directus_folders: directusFolderFields,
151
+ directus_operations: directusOperationFields,
152
+ directus_panels: directusPanelFields,
153
+ directus_roles: directusRoleFields,
154
+ directus_settings: directusSettingsFields,
155
+ directus_users: directusUserFields,
159
156
  };
@@ -0,0 +1,16 @@
1
+ import type { DirectusTemplateConfig } from '../types.js';
2
+ export interface TemplateInfo {
3
+ config: DirectusTemplateConfig;
4
+ frontendOptions: Array<{
5
+ id: string;
6
+ name: string;
7
+ path: string;
8
+ }>;
9
+ }
10
+ /**
11
+ * Read and validate the template configuration from a directory
12
+ * @param dir Directory containing the template
13
+ * @returns Template configuration and frontend options
14
+ * @throws Error if package.json is missing or invalid
15
+ */
16
+ export declare function readTemplateConfig(dir: string): TemplateInfo | null;
@@ -0,0 +1,34 @@
1
+ import fs from 'node:fs';
2
+ import path from 'pathe';
3
+ /**
4
+ * Read and validate the template configuration from a directory
5
+ * @param dir Directory containing the template
6
+ * @returns Template configuration and frontend options
7
+ * @throws Error if package.json is missing or invalid
8
+ */
9
+ export function readTemplateConfig(dir) {
10
+ try {
11
+ const packageJsonPath = path.join(dir, 'package.json');
12
+ if (!fs.existsSync(packageJsonPath)) {
13
+ return null;
14
+ }
15
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
16
+ const templateConfig = packageJson['directus:template'];
17
+ if (!templateConfig) {
18
+ return null;
19
+ }
20
+ // Convert frontends object to array of options
21
+ const frontendOptions = Object.entries(templateConfig.frontends || {}).map(([id, frontend]) => ({
22
+ id,
23
+ name: frontend.name,
24
+ path: frontend.path.replace(/^\.\//, ''), // Remove leading ./
25
+ }));
26
+ return {
27
+ config: templateConfig,
28
+ frontendOptions,
29
+ };
30
+ }
31
+ catch (error) {
32
+ return null;
33
+ }
34
+ }
@@ -1,2 +1,2 @@
1
- export declare const generatePackageJsonContent: (templateName: string) => string;
1
+ export declare function generatePackageJsonContent(templateName: string): string;
2
2
  export declare const generateReadmeContent: (templateName: string) => string;
@@ -1,13 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateReadmeContent = exports.generatePackageJsonContent = void 0;
4
- const tslib_1 = require("tslib");
5
- const slugify_1 = tslib_1.__importDefault(require("slugify"));
6
- const generatePackageJsonContent = (templateName) => {
7
- const slugifiedName = (0, slugify_1.default)(templateName, {
8
- lower: true, // Convert to lowercase
9
- strict: true, // Remove special characters
10
- });
1
+ import slugify from '@sindresorhus/slugify';
2
+ export function generatePackageJsonContent(templateName) {
3
+ const slugifiedName = slugify(templateName);
11
4
  const packageName = `directus-template-${slugifiedName}`;
12
5
  return JSON.stringify({
13
6
  author: '',
@@ -18,9 +11,8 @@ const generatePackageJsonContent = (templateName) => {
18
11
  templateName,
19
12
  version: '1.0.0',
20
13
  }, null, 2);
21
- };
22
- exports.generatePackageJsonContent = generatePackageJsonContent;
23
- const generateReadmeContent = (templateName) => `# ${templateName} Template
14
+ }
15
+ export const generateReadmeContent = (templateName) => `# ${templateName} Template
24
16
 
25
17
  This is a template for [Directus](https://directus.io/) - an open-source headless CMS and API. Use the template-cli to load / apply this template to a blank instance.
26
18
 
@@ -31,4 +23,3 @@ This is a template for [Directus](https://directus.io/) - an open-source headles
31
23
  ## License
32
24
 
33
25
  `;
34
- exports.generateReadmeContent = generateReadmeContent;
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformGitHubUrl = void 0;
4
- function transformGitHubUrl(url) {
1
+ export function transformGitHubUrl(url) {
5
2
  // Regular expression to capture the repository name and any subsequent path after the 'tree'
6
3
  const regex = /github\.com\/([^/]+\/[^/]+)(?:\/tree\/[^/]+\/(.*))?$/;
7
4
  const match = url.match(regex);
@@ -12,4 +9,3 @@ function transformGitHubUrl(url) {
12
9
  }
13
10
  return 'Invalid URL';
14
11
  }
15
- exports.transformGitHubUrl = transformGitHubUrl;
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const protected_domains_1 = require("./protected-domains");
4
- function validateUrl(url) {
1
+ import { protectedDomains } from './protected-domains.js';
2
+ export default function validateUrl(url) {
5
3
  try {
6
4
  const parsedUrl = new URL(url);
7
- return !protected_domains_1.protectedDomains.includes(parsedUrl.hostname);
5
+ return !protectedDomains.includes(parsedUrl.hostname);
8
6
  }
9
7
  catch {
10
8
  return false;
11
9
  }
12
10
  }
13
- exports.default = validateUrl;
@@ -0,0 +1,7 @@
1
+ interface WaitOptions {
2
+ errorMessage?: string;
3
+ interval?: number;
4
+ maxAttempts?: number;
5
+ }
6
+ export declare function waitFor(checkFn: () => Promise<boolean>, options?: WaitOptions): Promise<boolean>;
7
+ export {};
@@ -0,0 +1,9 @@
1
+ export async function waitFor(checkFn, options = {}) {
2
+ const { errorMessage = 'Operation timed out', interval = 2000, maxAttempts = 30, } = options;
3
+ for (let i = 0; i < maxAttempts; i++) {
4
+ if (await checkFn())
5
+ return true;
6
+ await new Promise(resolve => setTimeout(resolve, interval));
7
+ }
8
+ throw new Error(errorMessage);
9
+ }
@@ -1,23 +1,20 @@
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
- exports.default = async (fileName, data, dir) => {
1
+ import fs from 'node:fs';
2
+ import path from 'pathe';
3
+ export default async (fileName, data, dir) => {
7
4
  const folders = fileName.split('/');
8
5
  const endFileName = folders.pop();
9
6
  const folderPath = folders.join('/');
10
7
  // Generate the full path where you want to write the file
11
- const fullPath = node_path_1.default.join(dir, folderPath);
8
+ const fullPath = path.join(dir, folderPath);
12
9
  // Check if the directory exists. Create if it doesn't.
13
- if (!node_fs_1.default.existsSync(fullPath)) {
14
- node_fs_1.default.mkdirSync(fullPath, { recursive: true });
10
+ if (!fs.existsSync(fullPath)) {
11
+ fs.mkdirSync(fullPath, { recursive: true });
15
12
  }
16
13
  // Construct the full file path
17
- const fullFilePath = node_path_1.default.join(fullPath, `${endFileName}.json`);
14
+ const fullFilePath = path.join(fullPath, `${endFileName}.json`);
18
15
  try {
19
16
  // Write the file
20
- await node_fs_1.default.promises.writeFile(fullFilePath, JSON.stringify(data, null, 2));
17
+ await fs.promises.writeFile(fullFilePath, JSON.stringify(data, null, 2));
21
18
  // console.log(`Wrote ${fullFilePath}`);
22
19
  }
23
20
  catch (error) {
@@ -0,0 +1,23 @@
1
+ export interface DockerConfig {
2
+ composeFile: string;
3
+ healthCheckEndpoint: string;
4
+ interval: number;
5
+ maxAttempts: number;
6
+ }
7
+ export interface DockerService {
8
+ checkDocker: () => Promise<DockerCheckResult>;
9
+ startContainers: (cwd: string) => Promise<void>;
10
+ stopContainers: (cwd: string) => Promise<void>;
11
+ waitForHealthy: (healthCheckUrl: string) => Promise<boolean>;
12
+ }
13
+ export interface DockerCheckResult {
14
+ installed: boolean;
15
+ message?: string;
16
+ running: boolean;
17
+ }
18
+ /**
19
+ * Create a Docker service instance
20
+ * @param {DockerConfig} config - The Docker configuration
21
+ * @returns {DockerService} - Returns a Docker service instance
22
+ */
23
+ export declare function createDocker(config: DockerConfig): DockerService;