gitlab-catalog-browser 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +75 -0
  3. package/bin/gitlab-ci-cli.js +29 -0
  4. package/dist/api/catalog.d.ts +38 -0
  5. package/dist/api/catalog.d.ts.map +1 -0
  6. package/dist/api/catalog.js +72 -0
  7. package/dist/api/catalog.js.map +1 -0
  8. package/dist/api/gitlab.d.ts +69 -0
  9. package/dist/api/gitlab.d.ts.map +1 -0
  10. package/dist/api/gitlab.js +226 -0
  11. package/dist/api/gitlab.js.map +1 -0
  12. package/dist/api/lint.d.ts +61 -0
  13. package/dist/api/lint.d.ts.map +1 -0
  14. package/dist/api/lint.js +41 -0
  15. package/dist/api/lint.js.map +1 -0
  16. package/dist/cache/schema-cache.d.ts +54 -0
  17. package/dist/cache/schema-cache.d.ts.map +1 -0
  18. package/dist/cache/schema-cache.js +124 -0
  19. package/dist/cache/schema-cache.js.map +1 -0
  20. package/dist/commands/batch.d.ts +19 -0
  21. package/dist/commands/batch.d.ts.map +1 -0
  22. package/dist/commands/batch.js +174 -0
  23. package/dist/commands/batch.js.map +1 -0
  24. package/dist/commands/catalog.d.ts +42 -0
  25. package/dist/commands/catalog.d.ts.map +1 -0
  26. package/dist/commands/catalog.js +158 -0
  27. package/dist/commands/catalog.js.map +1 -0
  28. package/dist/commands/component.d.ts +46 -0
  29. package/dist/commands/component.d.ts.map +1 -0
  30. package/dist/commands/component.js +213 -0
  31. package/dist/commands/component.js.map +1 -0
  32. package/dist/commands/pipeline.d.ts +61 -0
  33. package/dist/commands/pipeline.d.ts.map +1 -0
  34. package/dist/commands/pipeline.js +880 -0
  35. package/dist/commands/pipeline.js.map +1 -0
  36. package/dist/commands/setup.d.ts +119 -0
  37. package/dist/commands/setup.d.ts.map +1 -0
  38. package/dist/commands/setup.js +391 -0
  39. package/dist/commands/setup.js.map +1 -0
  40. package/dist/commands/skills.d.ts +39 -0
  41. package/dist/commands/skills.d.ts.map +1 -0
  42. package/dist/commands/skills.js +208 -0
  43. package/dist/commands/skills.js.map +1 -0
  44. package/dist/commands/validate.d.ts +27 -0
  45. package/dist/commands/validate.d.ts.map +1 -0
  46. package/dist/commands/validate.js +201 -0
  47. package/dist/commands/validate.js.map +1 -0
  48. package/dist/config/loader.d.ts +80 -0
  49. package/dist/config/loader.d.ts.map +1 -0
  50. package/dist/config/loader.js +217 -0
  51. package/dist/config/loader.js.map +1 -0
  52. package/dist/config/types.d.ts +46 -0
  53. package/dist/config/types.d.ts.map +1 -0
  54. package/dist/config/types.js +45 -0
  55. package/dist/config/types.js.map +1 -0
  56. package/dist/index.d.ts +10 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +437 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/output/table.d.ts +28 -0
  61. package/dist/output/table.d.ts.map +1 -0
  62. package/dist/output/table.js +67 -0
  63. package/dist/output/table.js.map +1 -0
  64. package/dist/types/api.d.ts +66 -0
  65. package/dist/types/api.d.ts.map +1 -0
  66. package/dist/types/api.js +61 -0
  67. package/dist/types/api.js.map +1 -0
  68. package/dist/types/catalog.d.ts +77 -0
  69. package/dist/types/catalog.d.ts.map +1 -0
  70. package/dist/types/catalog.js +5 -0
  71. package/dist/types/catalog.js.map +1 -0
  72. package/package.json +60 -0
  73. package/skill-data/core/reference.md +127 -0
  74. package/skill-data/core/templates.md +97 -0
  75. package/skill-data/core/workflows.md +84 -0
  76. package/skill-data/manifest.json +12 -0
  77. package/skill-data/templates/basic-pipeline.yml +29 -0
  78. package/skill-data/templates/docker-build.yml +38 -0
  79. package/skill-data/templates/multi-stage.yml +43 -0
  80. package/skills/gitlab-catalog-browser/SKILL.md +49 -0
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Base GitLab API client.
3
+ *
4
+ * Provides authenticated HTTP access to GitLab REST APIs with:
5
+ * - Bearer token authentication
6
+ * - Configurable base URL and timeout
7
+ * - Structured error handling for all HTTP error codes
8
+ * - Pagination support
9
+ */
10
+ import { AuthenticationError, PermissionError, NotFoundError, RateLimitError, ServerError, NetworkError, ConfigurationError, } from '../types/api.js';
11
+ // ──────────────────────────────────────────────
12
+ // GitLabApiClient
13
+ // ──────────────────────────────────────────────
14
+ export class GitLabApiClient {
15
+ baseUrl;
16
+ token;
17
+ defaultTimeout;
18
+ debug;
19
+ constructor(config = {}) {
20
+ this.baseUrl = (config.gitlabUrl ?? 'https://gitlab.com').replace(/\/+$/, '');
21
+ this.token = config.token;
22
+ this.defaultTimeout = config.timeout ?? 30000;
23
+ this.debug = config.debug ?? false;
24
+ }
25
+ // ────────────────────────────────────────────
26
+ // Public HTTP methods
27
+ // ────────────────────────────────────────────
28
+ /**
29
+ * Send an authenticated GET request.
30
+ */
31
+ async get(path, options = {}) {
32
+ return this.request('GET', path, options);
33
+ }
34
+ /**
35
+ * Send an authenticated POST request with JSON body.
36
+ */
37
+ async post(path, options = {}) {
38
+ return this.request('POST', path, options);
39
+ }
40
+ /**
41
+ * Send an authenticated PUT request with JSON body.
42
+ */
43
+ async put(path, options = {}) {
44
+ return this.request('PUT', path, options);
45
+ }
46
+ /**
47
+ * Send an authenticated DELETE request.
48
+ */
49
+ async delete(path, options = {}) {
50
+ return this.request('DELETE', path, options);
51
+ }
52
+ // ────────────────────────────────────────────
53
+ // Pagination
54
+ // ────────────────────────────────────────────
55
+ /**
56
+ * Fetch a paginated list, returning all pages.
57
+ * Uses GitLab's standard `page`/`per_page` query parameter convention.
58
+ */
59
+ async getAll(path, options = {}) {
60
+ const { page = 1, perPage = 20, ...rest } = options;
61
+ const results = [];
62
+ let currentPage = page;
63
+ let hasMore = true;
64
+ while (hasMore) {
65
+ const data = await this.get(path, {
66
+ ...rest,
67
+ params: { ...rest.params, page: currentPage, per_page: perPage },
68
+ });
69
+ results.push(...data);
70
+ // If we got fewer items than perPage, we're on the last page
71
+ if (data.length < perPage) {
72
+ hasMore = false;
73
+ }
74
+ else {
75
+ currentPage++;
76
+ }
77
+ }
78
+ return results;
79
+ }
80
+ // ────────────────────────────────────────────
81
+ // Core request method
82
+ // ────────────────────────────────────────────
83
+ async request(method, path, options = {}) {
84
+ const startTime = Date.now();
85
+ // Validate token
86
+ if (!this.token) {
87
+ throw new ConfigurationError('No GitLab token configured. Set GITLAB_CI_CLI_TOKEN or add "token" to your config file.');
88
+ }
89
+ // Build URL
90
+ const cleanPath = path.startsWith('/') ? path : `/${path}`;
91
+ const url = new URL(`${this.baseUrl}${cleanPath}`);
92
+ // Add query parameters
93
+ if (options.params) {
94
+ for (const [key, value] of Object.entries(options.params)) {
95
+ if (value !== undefined) {
96
+ url.searchParams.set(key, String(value));
97
+ }
98
+ }
99
+ }
100
+ // Build headers
101
+ const headers = {
102
+ Authorization: `Bearer ${this.token}`,
103
+ Accept: 'application/json',
104
+ ...options.headers,
105
+ };
106
+ if (options.body !== undefined) {
107
+ headers['Content-Type'] = 'application/json';
108
+ }
109
+ // Abort controller for timeout
110
+ const timeoutMs = options.timeout ?? this.defaultTimeout;
111
+ const controller = new AbortController();
112
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
113
+ // Combine signals if both provided
114
+ const signal = options.signal
115
+ ? composeAbortSignals(options.signal, controller.signal)
116
+ : controller.signal;
117
+ try {
118
+ if (this.debug) {
119
+ console.error(`[GitLab API] ${method} ${url.toString()}`);
120
+ }
121
+ const response = await fetch(url.toString(), {
122
+ method,
123
+ headers,
124
+ body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
125
+ signal,
126
+ });
127
+ const duration = Date.now() - startTime;
128
+ if (this.debug) {
129
+ console.error(`[GitLab API] → ${response.status} (${duration}ms)`);
130
+ }
131
+ // Handle errors
132
+ if (!response.ok) {
133
+ const errorBody = await this.parseErrorBody(response);
134
+ this.throwHttpError(response.status, response.statusText, url.toString(), errorBody);
135
+ }
136
+ // Parse response body
137
+ const contentType = response.headers.get('content-type') ?? '';
138
+ if (contentType.includes('application/json')) {
139
+ return (await response.json());
140
+ }
141
+ // For non-JSON responses, return the status as unknown
142
+ return { status: response.status };
143
+ }
144
+ catch (err) {
145
+ // If it's already one of our typed errors, re-throw
146
+ if (err instanceof AuthenticationError ||
147
+ err instanceof PermissionError ||
148
+ err instanceof NotFoundError ||
149
+ err instanceof RateLimitError ||
150
+ err instanceof ServerError ||
151
+ err instanceof ConfigurationError) {
152
+ throw err;
153
+ }
154
+ // Check for abort (timeout)
155
+ if (err instanceof DOMException && err.name === 'AbortError') {
156
+ throw new NetworkError(this.baseUrl, `Request timed out after ${timeoutMs}ms`);
157
+ }
158
+ // Network or other errors
159
+ throw new NetworkError(this.baseUrl, err instanceof Error ? err.message : String(err));
160
+ }
161
+ finally {
162
+ clearTimeout(timeoutId);
163
+ }
164
+ }
165
+ // ────────────────────────────────────────────
166
+ // Error handling
167
+ // ────────────────────────────────────────────
168
+ /**
169
+ * Try to parse the error body from an unsuccessful response.
170
+ */
171
+ async parseErrorBody(response) {
172
+ try {
173
+ const body = (await response.json());
174
+ if (typeof body.message === 'string')
175
+ return body.message;
176
+ if (body.error)
177
+ return body.error;
178
+ }
179
+ catch {
180
+ // Ignore parse errors
181
+ }
182
+ return `HTTP ${response.status} ${response.statusText}`;
183
+ }
184
+ /**
185
+ * Throw the appropriate error type based on HTTP status code.
186
+ */
187
+ throwHttpError(status, statusText, url, message) {
188
+ switch (status) {
189
+ case 401:
190
+ throw new AuthenticationError();
191
+ case 403:
192
+ throw new PermissionError(message);
193
+ case 404:
194
+ throw new NotFoundError(url);
195
+ case 429:
196
+ throw new RateLimitError(`Rate limited: ${message}`);
197
+ default:
198
+ if (status >= 500) {
199
+ throw new ServerError(status, statusText);
200
+ }
201
+ // Generic HTTP error
202
+ throw new Error(`GitLab API error (${status}): ${message}`);
203
+ }
204
+ }
205
+ }
206
+ // ──────────────────────────────────────────────
207
+ // Helpers
208
+ // ──────────────────────────────────────────────
209
+ /**
210
+ * Compose two AbortSignals into one that aborts if either aborts.
211
+ */
212
+ function composeAbortSignals(s1, s2) {
213
+ const controller = new AbortController();
214
+ const onAbort = () => controller.abort();
215
+ s1.addEventListener('abort', onAbort);
216
+ s2.addEventListener('abort', onAbort);
217
+ // Clean up listeners if neither aborts
218
+ if (!s1.aborted && !s2.aborted) {
219
+ controller.signal.addEventListener('abort', () => {
220
+ s1.removeEventListener('abort', onAbort);
221
+ s2.removeEventListener('abort', onAbort);
222
+ });
223
+ }
224
+ return controller.signal;
225
+ }
226
+ //# sourceMappingURL=gitlab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../src/api/gitlab.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * CI Lint API methods for GitLab CI/CD pipeline validation.
3
+ *
4
+ * Provides typed methods for validating .gitlab-ci.yml content via the
5
+ * GitLab CI Lint API endpoint.
6
+ */
7
+ import { GitLabApiClient } from './gitlab.js';
8
+ export interface LintValidateOptions {
9
+ /** Project path for context-aware validation */
10
+ project?: string;
11
+ /** Whether to include job details in response */
12
+ includeJobs?: boolean;
13
+ /** Enable dry-run mode for rules evaluation */
14
+ dryRun?: boolean;
15
+ /** Simulated CI/CD variables (key-value pairs) for dry-run evaluation */
16
+ variables?: Record<string, string>;
17
+ }
18
+ export interface LintError {
19
+ line?: number;
20
+ column?: number;
21
+ message: string;
22
+ }
23
+ export interface LintWarning {
24
+ line?: number;
25
+ column?: number;
26
+ message: string;
27
+ }
28
+ export interface LintJob {
29
+ name: string;
30
+ stage: string;
31
+ /** Whether this job would execute (in dry-run mode) */
32
+ when?: string;
33
+ /** Why the job was excluded (in dry-run mode) */
34
+ except_reason?: string | null;
35
+ }
36
+ export interface LintResult {
37
+ /** Validation status */
38
+ status: 'valid' | 'invalid';
39
+ /** List of errors (empty if valid) */
40
+ errors: LintError[];
41
+ /** List of warnings */
42
+ warnings: LintWarning[];
43
+ /** List of jobs (when include_jobs or dry_run is true) */
44
+ jobs?: LintJob[];
45
+ /** Whether the pipeline is valid (for dry-run mode) */
46
+ valid?: boolean;
47
+ /** Merged YAML configuration */
48
+ merged_yaml?: string;
49
+ }
50
+ export declare class LintApi {
51
+ private readonly client;
52
+ constructor(client: GitLabApiClient);
53
+ /**
54
+ * Validate a .gitlab-ci.yml content string using the GitLab CI Lint API.
55
+ *
56
+ * @param content - The YAML content to validate
57
+ * @param options - Validation options (project context, dry-run, etc.)
58
+ */
59
+ validate(content: string, options?: LintValidateOptions): Promise<LintResult>;
60
+ }
61
+ //# sourceMappingURL=lint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/api/lint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM9C,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,sCAAsC;IACtC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,uBAAuB;IACvB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,uDAAuD;IACvD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,qBAAa,OAAO;IACN,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,eAAe;IAEpD;;;;;OAKG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC;CAwBxF"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * CI Lint API methods for GitLab CI/CD pipeline validation.
3
+ *
4
+ * Provides typed methods for validating .gitlab-ci.yml content via the
5
+ * GitLab CI Lint API endpoint.
6
+ */
7
+ // ──────────────────────────────────────────────
8
+ // LintApi
9
+ // ──────────────────────────────────────────────
10
+ export class LintApi {
11
+ client;
12
+ constructor(client) {
13
+ this.client = client;
14
+ }
15
+ /**
16
+ * Validate a .gitlab-ci.yml content string using the GitLab CI Lint API.
17
+ *
18
+ * @param content - The YAML content to validate
19
+ * @param options - Validation options (project context, dry-run, etc.)
20
+ */
21
+ async validate(content, options = {}) {
22
+ const body = {
23
+ content,
24
+ };
25
+ if (options.includeJobs) {
26
+ body.include_jobs = true;
27
+ }
28
+ if (options.dryRun) {
29
+ body.dry = true;
30
+ }
31
+ if (options.variables && Object.keys(options.variables).length > 0) {
32
+ body.variables = options.variables;
33
+ }
34
+ // If a project is specified, use the project-specific lint endpoint
35
+ const endpoint = options.project
36
+ ? `/projects/${encodeURIComponent(options.project)}/ci/lint`
37
+ : '/ci/lint';
38
+ return this.client.post(endpoint, { body });
39
+ }
40
+ }
41
+ //# sourceMappingURL=lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/api/lint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuDH,iDAAiD;AACjD,UAAU;AACV,iDAAiD;AAEjD,MAAM,OAAO,OAAO;IACW;IAA7B,YAA6B,MAAuB;QAAvB,WAAM,GAAN,MAAM,CAAiB;IAAG,CAAC;IAExD;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAe,EAAE,UAA+B,EAAE;QAC/D,MAAM,IAAI,GAA4B;YACpC,OAAO;SACR,CAAC;QAEF,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACrC,CAAC;QAED,oEAAoE;QACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO;YAC9B,CAAC,CAAC,aAAa,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU;YAC5D,CAAC,CAAC,UAAU,CAAC;QAEf,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAa,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;CACF"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Schema Cache — file-based JSON cache with TTL for component schema data.
3
+ *
4
+ * Cache entries are persisted in `.gitlab-ci-cli-cache.json` in the
5
+ * configured cache directory (default: current working directory).
6
+ * Supports configurable TTL via `GITLAB_CI_CLI_CACHE_TTL` env var (ms).
7
+ * Cache directory can be overridden via `GITLAB_CI_CLI_CACHE_DIR` env var.
8
+ */
9
+ export declare class SchemaCache {
10
+ private store;
11
+ private cacheDir;
12
+ private cachePath;
13
+ constructor(cacheDir?: string);
14
+ /**
15
+ * Get a value from cache. Returns null if not found or expired.
16
+ */
17
+ get<T>(key: string): {
18
+ data: T;
19
+ age: number;
20
+ } | null;
21
+ /**
22
+ * Set a value in cache with optional custom TTL.
23
+ */
24
+ set(key: string, data: unknown, ttl?: number): void;
25
+ /**
26
+ * Clear all cached entries.
27
+ */
28
+ clear(): void;
29
+ /**
30
+ * Remove a single entry from cache.
31
+ */
32
+ remove(key: string): void;
33
+ /**
34
+ * Get the number of cached entries.
35
+ */
36
+ get size(): number;
37
+ /**
38
+ * Load cache from disk.
39
+ */
40
+ private load;
41
+ /**
42
+ * Save cache to disk.
43
+ */
44
+ private save;
45
+ /**
46
+ * Resolve TTL from env var or default.
47
+ */
48
+ private resolveTtl;
49
+ }
50
+ /**
51
+ * Build a cache key for component schema requests.
52
+ */
53
+ export declare function buildComponentCacheKey(fullPath: string, version?: string): string;
54
+ //# sourceMappingURL=schema-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-cache.d.ts","sourceRoot":"","sources":["../../src/cache/schema-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0BH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,QAAQ,CAAC,EAAE,MAAM;IAM7B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAepD;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IASnD;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzB;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,OAAO,CAAC,IAAI;IASZ;;OAEG;IACH,OAAO,CAAC,IAAI;IAYZ;;OAEG;IACH,OAAO,CAAC,UAAU;CAQnB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAIR"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Schema Cache — file-based JSON cache with TTL for component schema data.
3
+ *
4
+ * Cache entries are persisted in `.gitlab-ci-cli-cache.json` in the
5
+ * configured cache directory (default: current working directory).
6
+ * Supports configurable TTL via `GITLAB_CI_CLI_CACHE_TTL` env var (ms).
7
+ * Cache directory can be overridden via `GITLAB_CI_CLI_CACHE_DIR` env var.
8
+ */
9
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ // ──────────────────────────────────────────────
12
+ // Types
13
+ // ──────────────────────────────────────────────
14
+ const DEFAULT_TTL = 5 * 60 * 1000; // 5 minutes in milliseconds
15
+ const CACHE_FILENAME = '.gitlab-ci-cli-cache.json';
16
+ // ──────────────────────────────────────────────
17
+ // SchemaCache
18
+ // ──────────────────────────────────────────────
19
+ export class SchemaCache {
20
+ store = {};
21
+ cacheDir;
22
+ cachePath;
23
+ constructor(cacheDir) {
24
+ this.cacheDir = cacheDir ?? process.env.GITLAB_CI_CLI_CACHE_DIR ?? process.cwd();
25
+ this.cachePath = join(this.cacheDir, CACHE_FILENAME);
26
+ this.load();
27
+ }
28
+ /**
29
+ * Get a value from cache. Returns null if not found or expired.
30
+ */
31
+ get(key) {
32
+ const entry = this.store[key];
33
+ if (!entry)
34
+ return null;
35
+ const age = Date.now() - entry.timestamp;
36
+ if (age > entry.ttl) {
37
+ // Expired — remove it
38
+ delete this.store[key];
39
+ this.save();
40
+ return null;
41
+ }
42
+ return { data: entry.data, age };
43
+ }
44
+ /**
45
+ * Set a value in cache with optional custom TTL.
46
+ */
47
+ set(key, data, ttl) {
48
+ this.store[key] = {
49
+ data,
50
+ timestamp: Date.now(),
51
+ ttl: ttl ?? this.resolveTtl(),
52
+ };
53
+ this.save();
54
+ }
55
+ /**
56
+ * Clear all cached entries.
57
+ */
58
+ clear() {
59
+ this.store = {};
60
+ this.save();
61
+ }
62
+ /**
63
+ * Remove a single entry from cache.
64
+ */
65
+ remove(key) {
66
+ delete this.store[key];
67
+ this.save();
68
+ }
69
+ /**
70
+ * Get the number of cached entries.
71
+ */
72
+ get size() {
73
+ return Object.keys(this.store).length;
74
+ }
75
+ /**
76
+ * Load cache from disk.
77
+ */
78
+ load() {
79
+ try {
80
+ const content = readFileSync(this.cachePath, 'utf-8');
81
+ this.store = JSON.parse(content);
82
+ }
83
+ catch {
84
+ this.store = {};
85
+ }
86
+ }
87
+ /**
88
+ * Save cache to disk.
89
+ */
90
+ save() {
91
+ try {
92
+ const dir = this.cacheDir;
93
+ if (!existsSync(dir)) {
94
+ mkdirSync(dir, { recursive: true });
95
+ }
96
+ writeFileSync(this.cachePath, JSON.stringify(this.store, null, 2), 'utf-8');
97
+ }
98
+ catch {
99
+ // Silently fail — cache is a performance optimization, not critical
100
+ }
101
+ }
102
+ /**
103
+ * Resolve TTL from env var or default.
104
+ */
105
+ resolveTtl() {
106
+ const envTtl = process.env.GITLAB_CI_CLI_CACHE_TTL;
107
+ if (envTtl) {
108
+ const parsed = parseInt(envTtl, 10);
109
+ if (!isNaN(parsed) && parsed > 0)
110
+ return parsed;
111
+ }
112
+ return DEFAULT_TTL;
113
+ }
114
+ }
115
+ /**
116
+ * Build a cache key for component schema requests.
117
+ */
118
+ export function buildComponentCacheKey(fullPath, version) {
119
+ const parts = ['component', fullPath];
120
+ if (version)
121
+ parts.push(version);
122
+ return parts.join(':');
123
+ }
124
+ //# sourceMappingURL=schema-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-cache.js","sourceRoot":"","sources":["../../src/cache/schema-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Batch command execution handler.
3
+ *
4
+ * Implements `batch` command for executing multiple CLI commands
5
+ * in a single invocation, sequentially.
6
+ */
7
+ import type { GitLabCIConfig } from '../config/types.js';
8
+ export interface BatchOptions {
9
+ bail?: boolean;
10
+ json?: boolean;
11
+ }
12
+ /**
13
+ * Handle `batch <commands...> [--bail]` or `batch --json` (stdin).
14
+ */
15
+ export declare function handleBatch(commands: string[] | undefined, _config: Partial<GitLabCIConfig>, options?: BatchOptions): Promise<{
16
+ exitCode: number;
17
+ output: string;
18
+ }>;
19
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/commands/batch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMzD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA0DD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,EAC9B,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,EAChC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkI/C"}