@airdraft/core 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 (42) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/adapters/GitHubAdapter.d.ts +69 -0
  3. package/dist/adapters/GitHubAdapter.d.ts.map +1 -0
  4. package/dist/adapters/GitHubAdapter.js +278 -0
  5. package/dist/adapters/GitHubAdapter.js.map +1 -0
  6. package/dist/adapters/LocalAdapter.d.ts +21 -0
  7. package/dist/adapters/LocalAdapter.d.ts.map +1 -0
  8. package/dist/adapters/LocalAdapter.js +109 -0
  9. package/dist/adapters/LocalAdapter.js.map +1 -0
  10. package/dist/config.d.ts +21 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +34 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/engine.d.ts +26 -0
  15. package/dist/engine.d.ts.map +1 -0
  16. package/dist/engine.js +379 -0
  17. package/dist/engine.js.map +1 -0
  18. package/dist/errors.d.ts +45 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +80 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/fields.d.ts +23 -0
  23. package/dist/fields.d.ts.map +1 -0
  24. package/dist/fields.js +181 -0
  25. package/dist/fields.js.map +1 -0
  26. package/dist/index.d.ts +10 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +11 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/publish.d.ts +20 -0
  31. package/dist/publish.d.ts.map +1 -0
  32. package/dist/publish.js +25 -0
  33. package/dist/publish.js.map +1 -0
  34. package/dist/slug.d.ts +21 -0
  35. package/dist/slug.d.ts.map +1 -0
  36. package/dist/slug.js +39 -0
  37. package/dist/slug.js.map +1 -0
  38. package/dist/types.d.ts +326 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +3 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +41 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@airdraft/core` will be documented here.
4
+
5
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
@@ -0,0 +1,69 @@
1
+ import type { StorageAdapter, FileResult, WriteOptions, DeleteOptions, FileListItem } from '../types.js';
2
+ export interface GitHubAdapterOptions {
3
+ /**
4
+ * GitHub App ID. Required when `tokenProvider` is not supplied.
5
+ */
6
+ appId?: string;
7
+ /**
8
+ * GitHub App private key (PEM). Required when `tokenProvider` is not supplied.
9
+ */
10
+ privateKey?: string;
11
+ /**
12
+ * GitHub App installation ID. Required when `tokenProvider` is not supplied.
13
+ */
14
+ installationId?: string;
15
+ /**
16
+ * Alternative to appId/privateKey/installationId. A function that returns a
17
+ * valid GitHub installation access token. When present, local JWT signing is
18
+ * skipped entirely. Used for mode 1 (cloud runtime) and mode 2 (self-hosted
19
+ * via Airdraft token relay).
20
+ */
21
+ tokenProvider?: () => Promise<string>;
22
+ /** "owner/repo" */
23
+ repo: string;
24
+ /** Defaults to repo default branch. */
25
+ branch?: string;
26
+ committer?: {
27
+ name: string;
28
+ email: string;
29
+ };
30
+ /**
31
+ * Read cache TTL in milliseconds (D3). Default: 30_000 (30 seconds).
32
+ * Set to 0 to disable caching.
33
+ */
34
+ cacheTtlMs?: number;
35
+ /**
36
+ * Maximum cached entries (D3). Default: 500.
37
+ */
38
+ cacheMaxSize?: number;
39
+ /**
40
+ * Override the default commit message template (D1).
41
+ * Receives action ('Create' | 'Update' | 'Delete'), collection name, and slug.
42
+ * Default: `"{Action} {collection}/{slug}"`
43
+ */
44
+ commitMessage?: (action: 'Create' | 'Update' | 'Delete', collection: string, slug: string) => string;
45
+ }
46
+ export interface CommitAuthor {
47
+ name: string;
48
+ email: string;
49
+ }
50
+ export declare class GitHubAdapter implements StorageAdapter {
51
+ private readonly opts;
52
+ private tokenCache;
53
+ private readonly readCache;
54
+ private readonly buildCommitMessage;
55
+ constructor(options: GitHubAdapterOptions);
56
+ private getToken;
57
+ private authHeaders;
58
+ private contentsUrl;
59
+ private fetch;
60
+ read(path: string): Promise<FileResult | null>;
61
+ write(path: string, content: string, options: WriteOptions & {
62
+ author?: CommitAuthor;
63
+ }): Promise<void>;
64
+ delete(path: string, options: DeleteOptions & {
65
+ author?: CommitAuthor;
66
+ }): Promise<void>;
67
+ list(glob: string): Promise<FileListItem[]>;
68
+ }
69
+ //# sourceMappingURL=GitHubAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/GitHubAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAQxG,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACrG;AAMD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAgID,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAsF;gBAE7G,OAAO,EAAE,oBAAoB;YA4B3B,QAAQ;YAoCR,WAAW;IASzB,OAAO,CAAC,WAAW;YAUL,KAAK;IA8Bb,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA2B9C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG;QAAE,MAAM,CAAC,EAAE,YAAY,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCtG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG;QAAE,MAAM,CAAC,EAAE,YAAY,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCvF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAoBlD"}
@@ -0,0 +1,278 @@
1
+ import { GitHubError, AdapterError } from '../errors.js';
2
+ import { createSign } from 'node:crypto';
3
+ // ---------------------------------------------------------------------------
4
+ // JWT helpers (Node.js 18+ crypto.subtle — no external deps)
5
+ // ---------------------------------------------------------------------------
6
+ function base64url(input) {
7
+ const buf = Buffer.isBuffer(input) ? input : Buffer.from(input);
8
+ return buf.toString('base64')
9
+ .replace(/\+/g, '-')
10
+ .replace(/\//g, '_')
11
+ .replace(/=+$/, '');
12
+ }
13
+ async function signJwt(appId, privateKeyPem) {
14
+ const now = Math.floor(Date.now() / 1000);
15
+ const header = base64url(Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })));
16
+ const payload = base64url(Buffer.from(JSON.stringify({ iat: now - 60, exp: now + 540, iss: appId })));
17
+ const signingInput = `${header}.${payload}`;
18
+ const normalizedKey = privateKeyPem.replace(/\\n/g, '\n');
19
+ const sign = createSign('RSA-SHA256');
20
+ sign.update(signingInput);
21
+ const signature = sign.sign(normalizedKey);
22
+ return `${signingInput}.${base64url(signature)}`;
23
+ }
24
+ class LruCache {
25
+ maxSize;
26
+ ttlMs;
27
+ map = new Map();
28
+ constructor(maxSize, ttlMs) {
29
+ this.maxSize = maxSize;
30
+ this.ttlMs = ttlMs;
31
+ }
32
+ get(key) {
33
+ const entry = this.map.get(key);
34
+ if (!entry)
35
+ return undefined;
36
+ if (Date.now() > entry.expiresAt) {
37
+ this.map.delete(key);
38
+ return undefined;
39
+ }
40
+ // Refresh LRU order
41
+ this.map.delete(key);
42
+ this.map.set(key, entry);
43
+ return entry.value;
44
+ }
45
+ set(key, value) {
46
+ if (this.map.has(key))
47
+ this.map.delete(key);
48
+ else if (this.map.size >= this.maxSize) {
49
+ // Evict the oldest entry (first key in insertion-order Map)
50
+ const oldest = this.map.keys().next().value;
51
+ if (oldest !== undefined)
52
+ this.map.delete(oldest);
53
+ }
54
+ this.map.set(key, { value, expiresAt: Date.now() + this.ttlMs });
55
+ }
56
+ delete(key) {
57
+ this.map.delete(key);
58
+ }
59
+ clear() {
60
+ this.map.clear();
61
+ }
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // Default commit message template (D1)
65
+ // ---------------------------------------------------------------------------
66
+ function defaultCommitMessage(action, collection, slug) {
67
+ return `${action} ${collection}/${slug}`;
68
+ }
69
+ export class GitHubAdapter {
70
+ opts;
71
+ tokenCache = null;
72
+ readCache;
73
+ buildCommitMessage;
74
+ constructor(options) {
75
+ const hasSigningCreds = options.appId && options.privateKey && options.installationId;
76
+ const hasProvider = typeof options.tokenProvider === 'function';
77
+ if (!hasSigningCreds && !hasProvider) {
78
+ throw new AdapterError('GitHubAdapter requires either (appId + privateKey + installationId) or a tokenProvider function');
79
+ }
80
+ this.opts = {
81
+ branch: '',
82
+ cacheTtlMs: 30_000,
83
+ cacheMaxSize: 500,
84
+ commitMessage: defaultCommitMessage,
85
+ ...options,
86
+ };
87
+ const ttl = options.cacheTtlMs ?? 30_000;
88
+ this.readCache = ttl > 0
89
+ ? new LruCache(options.cacheMaxSize ?? 500, ttl)
90
+ : new LruCache(0, 0); // effectively disabled
91
+ this.buildCommitMessage = options.commitMessage ?? defaultCommitMessage;
92
+ }
93
+ // -------------------------------------------------------------------------
94
+ // Token management
95
+ // -------------------------------------------------------------------------
96
+ async getToken() {
97
+ // Mode 1/2: delegate entirely to the provided token function
98
+ if (this.opts.tokenProvider) {
99
+ return this.opts.tokenProvider();
100
+ }
101
+ // Mode 3: local JWT signing path
102
+ const fiveMinutes = 5 * 60 * 1000;
103
+ if (this.tokenCache && this.tokenCache.expiresAt - Date.now() > fiveMinutes) {
104
+ return this.tokenCache.token;
105
+ }
106
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
107
+ const jwt = await signJwt(this.opts.appId, this.opts.privateKey);
108
+ const res = await this.fetch(
109
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
110
+ `https://api.github.com/app/installations/${this.opts.installationId}/access_tokens`, {
111
+ method: 'POST',
112
+ headers: {
113
+ Authorization: `Bearer ${jwt}`,
114
+ Accept: 'application/vnd.github+json',
115
+ 'X-GitHub-Api-Version': '2022-11-28',
116
+ },
117
+ }, 0 // no retry for token fetch
118
+ );
119
+ const body = await res.json();
120
+ this.tokenCache = {
121
+ token: body.token,
122
+ expiresAt: new Date(body.expires_at).getTime(),
123
+ };
124
+ return this.tokenCache.token;
125
+ }
126
+ async authHeaders() {
127
+ const token = await this.getToken();
128
+ return {
129
+ Authorization: `Bearer ${token}`,
130
+ Accept: 'application/vnd.github+json',
131
+ 'X-GitHub-Api-Version': '2022-11-28',
132
+ };
133
+ }
134
+ contentsUrl(path) {
135
+ const [owner, repo] = this.opts.repo.split('/');
136
+ const base = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
137
+ return this.opts.branch ? `${base}?ref=${this.opts.branch}` : base;
138
+ }
139
+ // -------------------------------------------------------------------------
140
+ // Fetch with retry
141
+ // -------------------------------------------------------------------------
142
+ async fetch(url, init, maxRetries = 3) {
143
+ let lastErr;
144
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
145
+ if (attempt > 0) {
146
+ await sleep(Math.min(1000 * 2 ** (attempt - 1), 8000));
147
+ }
148
+ let res;
149
+ try {
150
+ res = await fetch(url, init);
151
+ }
152
+ catch (err) {
153
+ lastErr = err;
154
+ continue;
155
+ }
156
+ if (res.ok)
157
+ return res;
158
+ // Non-retriable
159
+ if ([400, 401, 403, 404, 409, 422].includes(res.status)) {
160
+ return res;
161
+ }
162
+ // Retriable (5xx, 429)
163
+ lastErr = new GitHubError(`GitHub API ${res.status}: ${url}`);
164
+ }
165
+ throw new GitHubError(`GitHub API call failed after ${maxRetries + 1} attempts: ${String(lastErr)}`);
166
+ }
167
+ // -------------------------------------------------------------------------
168
+ // StorageAdapter implementation
169
+ // -------------------------------------------------------------------------
170
+ async read(path) {
171
+ // Check LRU cache first (D3)
172
+ const cacheKey = `${this.opts.repo}/${this.opts.branch}/${path}`;
173
+ const cached = this.readCache.get(cacheKey);
174
+ if (cached !== undefined)
175
+ return cached;
176
+ const headers = await this.authHeaders();
177
+ const res = await this.fetch(this.contentsUrl(path), { headers });
178
+ if (res.status === 404) {
179
+ this.readCache.set(cacheKey, null);
180
+ return null;
181
+ }
182
+ if (!res.ok) {
183
+ throw new GitHubError(`Failed to read "${path}": ${res.status} ${res.statusText}`);
184
+ }
185
+ const data = await res.json();
186
+ if (data.encoding !== 'base64') {
187
+ throw new AdapterError(`Unexpected encoding "${data.encoding}" for "${path}"`);
188
+ }
189
+ const content = atob(data.content.replace(/\n/g, ''));
190
+ const result = { content, sha: data.sha, path };
191
+ this.readCache.set(cacheKey, result);
192
+ return result;
193
+ }
194
+ async write(path, content, options) {
195
+ const headers = await this.authHeaders();
196
+ const encoded = btoa(unescape(encodeURIComponent(content)));
197
+ // Derive collection + slug from path for commit message (D1)
198
+ const [, collection = 'unknown', slug = 'unknown'] = path.match(/^([^/]+)\/(.+?)(?:\.[^.]+)?$/) ?? [];
199
+ const body = {
200
+ message: options.message || this.buildCommitMessage('Update', collection, slug),
201
+ content: encoded,
202
+ };
203
+ if (options.sha)
204
+ body['sha'] = options.sha;
205
+ if (options.branch ?? this.opts.branch)
206
+ body['branch'] = options.branch ?? this.opts.branch;
207
+ if (this.opts.committer)
208
+ body['committer'] = this.opts.committer;
209
+ // Co-authored-by trailer (D2)
210
+ if (options.author) {
211
+ body['message'] = `${body['message']}\n\nCo-authored-by: ${options.author.name} <${options.author.email}>`;
212
+ }
213
+ const res = await this.fetch(this.contentsUrl(path), {
214
+ method: 'PUT',
215
+ headers: { ...headers, 'Content-Type': 'application/json' },
216
+ body: JSON.stringify(body),
217
+ });
218
+ if (!res.ok) {
219
+ const err = await res.json().catch(() => ({}));
220
+ throw new GitHubError(`Failed to write "${path}": ${res.status} ${err.message ?? res.statusText}`);
221
+ }
222
+ // Invalidate cache on write (D3)
223
+ const cacheKey = `${this.opts.repo}/${this.opts.branch}/${path}`;
224
+ this.readCache.delete(cacheKey);
225
+ }
226
+ async delete(path, options) {
227
+ const headers = await this.authHeaders();
228
+ const [owner, repo] = this.opts.repo.split('/');
229
+ const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
230
+ // Derive collection + slug from path for commit message (D1)
231
+ const [, collection = 'unknown', slug = 'unknown'] = path.match(/^([^/]+)\/(.+?)(?:\.[^.]+)?$/) ?? [];
232
+ let message = options.message || this.buildCommitMessage('Delete', collection, slug);
233
+ // Co-authored-by trailer (D2)
234
+ if (options.author) {
235
+ message = `${message}\n\nCo-authored-by: ${options.author.name} <${options.author.email}>`;
236
+ }
237
+ const body = { message, sha: options.sha };
238
+ if (options.branch ?? this.opts.branch)
239
+ body['branch'] = options.branch ?? this.opts.branch;
240
+ if (this.opts.committer)
241
+ body['committer'] = this.opts.committer;
242
+ const res = await this.fetch(url, {
243
+ method: 'DELETE',
244
+ headers: { ...headers, 'Content-Type': 'application/json' },
245
+ body: JSON.stringify(body),
246
+ });
247
+ if (!res.ok) {
248
+ const err = await res.json().catch(() => ({}));
249
+ throw new GitHubError(`Failed to delete "${path}": ${res.status} ${err.message ?? res.statusText}`);
250
+ }
251
+ // Invalidate cache on delete (D3)
252
+ const cacheKey = `${this.opts.repo}/${this.opts.branch}/${path}`;
253
+ this.readCache.delete(cacheKey);
254
+ }
255
+ async list(glob) {
256
+ // Resolve directory from glob prefix (before first wildcard)
257
+ const prefix = glob.split('*')[0];
258
+ const dir = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix.split('/').slice(0, -1).join('/');
259
+ const headers = await this.authHeaders();
260
+ const [owner, repo] = this.opts.repo.split('/');
261
+ const branch = this.opts.branch ? `?ref=${this.opts.branch}` : '';
262
+ const url = `https://api.github.com/repos/${owner}/${repo}/contents/${dir}${branch}`;
263
+ const res = await this.fetch(url, { headers });
264
+ if (res.status === 404)
265
+ return [];
266
+ if (!res.ok) {
267
+ throw new GitHubError(`Failed to list "${dir}": ${res.status} ${res.statusText}`);
268
+ }
269
+ const items = await res.json();
270
+ return items
271
+ .filter((item) => item.type === 'file')
272
+ .map((item) => ({ path: item.path, sha: item.sha }));
273
+ }
274
+ }
275
+ function sleep(ms) {
276
+ return new Promise((resolve) => setTimeout(resolve, ms));
277
+ }
278
+ //# sourceMappingURL=GitHubAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubAdapter.js","sourceRoot":"","sources":["../../src/adapters/GitHubAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { StorageAdapter, FileResult, WriteOptions, DeleteOptions, FileListItem } from '../types.js';
2
+ export interface LocalAdapterOptions {
3
+ /** Absolute or cwd-relative root directory for content files. */
4
+ root: string;
5
+ }
6
+ /**
7
+ * LocalAdapter — reads/writes files directly on disk.
8
+ * Designed for local development and testing.
9
+ * Set GITCMS_LOCAL=true (with no GitHub env vars) to activate automatically.
10
+ */
11
+ export declare class LocalAdapter implements StorageAdapter {
12
+ private readonly root;
13
+ constructor(options: LocalAdapterOptions);
14
+ private abs;
15
+ private sha;
16
+ read(path: string): Promise<FileResult | null>;
17
+ write(path: string, content: string, _options: WriteOptions): Promise<void>;
18
+ delete(path: string, _options: DeleteOptions): Promise<void>;
19
+ list(glob: string): Promise<FileListItem[]>;
20
+ }
21
+ //# sourceMappingURL=LocalAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/LocalAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGxG,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,qBAAa,YAAa,YAAW,cAAc;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;gBAEjB,OAAO,EAAE,mBAAmB;IAIxC,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,GAAG;IAIL,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAW9C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAU3E,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAclD"}
@@ -0,0 +1,109 @@
1
+ import { readFile, writeFile, rm, readdir, stat } from 'node:fs/promises';
2
+ import { resolve, join, relative, dirname } from 'node:path';
3
+ import { mkdir } from 'node:fs/promises';
4
+ import { createHash } from 'node:crypto';
5
+ import { AdapterError } from '../errors.js';
6
+ /**
7
+ * LocalAdapter — reads/writes files directly on disk.
8
+ * Designed for local development and testing.
9
+ * Set GITCMS_LOCAL=true (with no GitHub env vars) to activate automatically.
10
+ */
11
+ export class LocalAdapter {
12
+ root;
13
+ constructor(options) {
14
+ this.root = resolve(process.cwd(), options.root);
15
+ }
16
+ abs(path) {
17
+ return join(this.root, path);
18
+ }
19
+ sha(content) {
20
+ return createHash('sha1').update(content).digest('hex');
21
+ }
22
+ async read(path) {
23
+ const abs = this.abs(path);
24
+ try {
25
+ const content = await readFile(abs, 'utf8');
26
+ return { content, sha: this.sha(content), path };
27
+ }
28
+ catch (err) {
29
+ if (isNodeError(err) && err.code === 'ENOENT')
30
+ return null;
31
+ throw new AdapterError(`Failed to read "${path}"`, err);
32
+ }
33
+ }
34
+ async write(path, content, _options) {
35
+ const abs = this.abs(path);
36
+ try {
37
+ await mkdir(dirname(abs), { recursive: true });
38
+ await writeFile(abs, content, 'utf8');
39
+ }
40
+ catch (err) {
41
+ throw new AdapterError(`Failed to write "${path}"`, err);
42
+ }
43
+ }
44
+ async delete(path, _options) {
45
+ const abs = this.abs(path);
46
+ try {
47
+ await rm(abs, { force: true });
48
+ }
49
+ catch (err) {
50
+ throw new AdapterError(`Failed to delete "${path}"`, err);
51
+ }
52
+ }
53
+ async list(glob) {
54
+ // Simple glob: supports a single leading segment + trailing '*' or '**' wildcard
55
+ // For production a proper glob library will replace this minimal impl
56
+ const prefix = glob.replace(/\*.*$/, '');
57
+ const dir = this.abs(prefix);
58
+ try {
59
+ const results = [];
60
+ await walk(dir, dir, glob.replace(prefix, ''), results, this.root);
61
+ return results;
62
+ }
63
+ catch (err) {
64
+ if (isNodeError(err) && err.code === 'ENOENT')
65
+ return [];
66
+ throw new AdapterError(`Failed to list "${glob}"`, err);
67
+ }
68
+ }
69
+ }
70
+ async function walk(base, dir, suffix, out, root) {
71
+ // Derive an optional extension filter from the suffix glob (e.g. '*.md' → '.md').
72
+ // A bare '*' or '**' means accept all extensions.
73
+ const extFilter = /^\*\.(\w+)$/.exec(suffix)?.[1]
74
+ ? `.${/^\*\.(\w+)$/.exec(suffix)[1]}`
75
+ : null;
76
+ let entries;
77
+ try {
78
+ entries = await readdir(dir);
79
+ }
80
+ catch {
81
+ return;
82
+ }
83
+ for (const entry of entries) {
84
+ const full = join(dir, entry);
85
+ const s = await stat(full).catch(() => null);
86
+ if (!s)
87
+ continue;
88
+ if (s.isDirectory()) {
89
+ await walk(base, full, suffix, out, root);
90
+ }
91
+ else {
92
+ if (extFilter && !entry.endsWith(extFilter))
93
+ continue;
94
+ const rel = relative(root, full);
95
+ let content;
96
+ try {
97
+ content = await readFile(full, 'utf8');
98
+ }
99
+ catch {
100
+ continue;
101
+ }
102
+ out.push({ path: rel, sha: createHash('sha1').update(content).digest('hex') });
103
+ }
104
+ }
105
+ }
106
+ function isNodeError(err) {
107
+ return typeof err === 'object' && err !== null && 'code' in err;
108
+ }
109
+ //# sourceMappingURL=LocalAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalAdapter.js","sourceRoot":"","sources":["../../src/adapters/LocalAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { CmsConfig, CollectionMap, Plugin, StorageAdapter, Entry } from './types.js';
2
+ export interface DefineConfigOptions {
3
+ adapter: StorageAdapter;
4
+ /** Inline collection definitions. Mutually exclusive with `schemaPath`. */
5
+ collections?: CollectionMap;
6
+ /**
7
+ * Path to an `airdraft.schema.json` file (relative to `process.cwd()`).
8
+ * Mutually exclusive with `collections`.
9
+ */
10
+ schemaPath?: string;
11
+ plugins?: Plugin[];
12
+ basePath?: string;
13
+ defaultLocale?: string;
14
+ revalidation?: Record<string, (entry: Entry) => string[]>;
15
+ }
16
+ /**
17
+ * Entry point for all Airdraft configuration.
18
+ * Returns a typed CmsConfig object consumed by framework adapters.
19
+ */
20
+ export declare function defineConfig(options: DefineConfigOptions): CmsConfig;
21
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEzF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,CAAA;IACvB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,aAAa,CAAA;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,EAAE,CAAC,CAAA;CAC1D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,CA2BpE"}
package/dist/config.js ADDED
@@ -0,0 +1,34 @@
1
+ import { readFileSync } from 'fs';
2
+ import { resolve } from 'path';
3
+ /**
4
+ * Entry point for all Airdraft configuration.
5
+ * Returns a typed CmsConfig object consumed by framework adapters.
6
+ */
7
+ export function defineConfig(options) {
8
+ if (options.collections && options.schemaPath) {
9
+ throw new Error('[airdraft] defineConfig: "collections" and "schemaPath" are mutually exclusive.');
10
+ }
11
+ if (!options.collections && !options.schemaPath) {
12
+ throw new Error('[airdraft] defineConfig: one of "collections" or "schemaPath" must be provided.');
13
+ }
14
+ let collections;
15
+ if (options.schemaPath) {
16
+ const absPath = resolve(process.cwd(), options.schemaPath);
17
+ const raw = readFileSync(absPath, 'utf-8');
18
+ const parsed = JSON.parse(raw);
19
+ collections = parsed.collections;
20
+ }
21
+ else {
22
+ collections = options.collections;
23
+ }
24
+ return {
25
+ adapter: options.adapter,
26
+ collections,
27
+ plugins: options.plugins ?? [],
28
+ basePath: options.basePath ?? '/api/cms',
29
+ defaultLocale: options.defaultLocale,
30
+ revalidation: options.revalidation,
31
+ schemaPath: options.schemaPath,
32
+ };
33
+ }
34
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAkB9B;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B;IACvD,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAA;IACpG,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAA;IACpG,CAAC;IAED,IAAI,WAA0B,CAAA;IAC9B,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;QAC1D,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqD,CAAA;QAClF,WAAW,GAAG,MAAM,CAAC,WAAW,CAAA;IAClC,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,OAAO,CAAC,WAAY,CAAA;IACpC,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW;QACX,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;QAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,UAAU;QACxC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAA;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { CmsConfig, CollectionConfig, CmsSchema, Entry, ListOptions, GetOptions } from './types.js';
2
+ /**
3
+ * The core runtime class. Instantiated by framework adapters.
4
+ * Not part of the public API surface — do not use directly in application code.
5
+ */
6
+ export declare class CmsEngine {
7
+ private readonly config;
8
+ /** Collections after all plugin.schema() transforms have been applied. */
9
+ private readonly resolvedCollections;
10
+ constructor(config: CmsConfig);
11
+ getSchema(): CmsSchema;
12
+ getCollection(name: string): CollectionConfig | null;
13
+ private requireCollection;
14
+ listEntries(collection: string, options?: ListOptions): Promise<Entry[]>;
15
+ getEntry(collection: string, slug: string, options?: GetOptions): Promise<Entry | null>;
16
+ createEntry(collection: string, slugOrUndefined: string | undefined, data: Record<string, unknown>): Promise<Entry>;
17
+ updateEntry(collection: string, slug: string, data: Record<string, unknown>): Promise<Entry>;
18
+ deleteEntry(collection: string, slug: string, sha: string): Promise<void>;
19
+ private buildEntry;
20
+ private extractSlugFromPath;
21
+ private runReadHooks;
22
+ private runWriteHooks;
23
+ private runDeleteHooks;
24
+ private expandEntry;
25
+ }
26
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAEhB,SAAS,EACT,KAAK,EACL,WAAW,EACX,UAAU,EAIX,MAAM,YAAY,CAAA;AAwGnB;;;GAGG;AACH,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAe;gBAEtB,MAAM,EAAE,SAAS;IAY9C,SAAS,IAAI,SAAS;IAItB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAIpD,OAAO,CAAC,iBAAiB;IAUnB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAmE5E,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAsB3F,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,KAAK,CAAC;IAoDX,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,KAAK,CAAC;IAiDX,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB/E,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,mBAAmB;YASb,YAAY;YAMZ,aAAa;YAUb,cAAc;YAcd,WAAW;CA4B1B"}