@airdraft/cloud 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 (58) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/billing.d.ts +72 -0
  3. package/dist/billing.d.ts.map +1 -0
  4. package/dist/billing.js +204 -0
  5. package/dist/billing.js.map +1 -0
  6. package/dist/callback.d.ts +39 -0
  7. package/dist/callback.d.ts.map +1 -0
  8. package/dist/callback.js +178 -0
  9. package/dist/callback.js.map +1 -0
  10. package/dist/cli.d.ts +18 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +59 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/db.d.ts +13 -0
  15. package/dist/db.d.ts.map +1 -0
  16. package/dist/db.js +23 -0
  17. package/dist/db.js.map +1 -0
  18. package/dist/index.d.ts +20 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +19 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/invite.d.ts +28 -0
  23. package/dist/invite.d.ts.map +1 -0
  24. package/dist/invite.js +155 -0
  25. package/dist/invite.js.map +1 -0
  26. package/dist/jwt.d.ts +9 -0
  27. package/dist/jwt.d.ts.map +1 -0
  28. package/dist/jwt.js +32 -0
  29. package/dist/jwt.js.map +1 -0
  30. package/dist/project.d.ts +30 -0
  31. package/dist/project.d.ts.map +1 -0
  32. package/dist/project.js +145 -0
  33. package/dist/project.js.map +1 -0
  34. package/dist/relay.d.ts +35 -0
  35. package/dist/relay.d.ts.map +1 -0
  36. package/dist/relay.js +101 -0
  37. package/dist/relay.js.map +1 -0
  38. package/dist/runtime.d.ts +48 -0
  39. package/dist/runtime.d.ts.map +1 -0
  40. package/dist/runtime.js +186 -0
  41. package/dist/runtime.js.map +1 -0
  42. package/dist/state.d.ts +40 -0
  43. package/dist/state.d.ts.map +1 -0
  44. package/dist/state.js +58 -0
  45. package/dist/state.js.map +1 -0
  46. package/dist/team.d.ts +31 -0
  47. package/dist/team.d.ts.map +1 -0
  48. package/dist/team.js +150 -0
  49. package/dist/team.js.map +1 -0
  50. package/dist/types.d.ts +161 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +2 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/webhook.d.ts +29 -0
  55. package/dist/webhook.d.ts.map +1 -0
  56. package/dist/webhook.js +125 -0
  57. package/dist/webhook.js.map +1 -0
  58. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.js","sourceRoot":"","sources":["../src/team.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ import type { ObjectId, Collection } from 'mongodb';
2
+ /**
3
+ * A GitHub App installation connection on a project.
4
+ * Stored as a sub-document on `ProjectDoc.github`.
5
+ */
6
+ export interface GitHubConnection {
7
+ installationId: number;
8
+ /** "owner/repo" */
9
+ repo: string;
10
+ /** Write branch — one per project in v1. */
11
+ branch: string;
12
+ connectedAt: Date;
13
+ /** userId of the admin who initiated the connection. */
14
+ connectedBy: string;
15
+ }
16
+ /** Projects collection — one per team repository connection. */
17
+ export interface ProjectDoc {
18
+ _id: ObjectId;
19
+ teamId: string;
20
+ name: string;
21
+ slug: string;
22
+ /** SHA-256 hash of the project API key (`ntk_*`). null = no key generated yet. */
23
+ apiKeyHash: string | null;
24
+ /** null = GitHub App not yet connected. */
25
+ github: GitHubConnection | null;
26
+ createdAt: Date;
27
+ updatedAt: Date;
28
+ }
29
+ /** Teams collection — an org/workspace that owns projects and members. */
30
+ export interface TeamDoc {
31
+ _id: ObjectId;
32
+ name: string;
33
+ slug: string;
34
+ /** userId of the team creator. */
35
+ ownerId: string;
36
+ /** Slug referencing a PlanDoc (e.g. 'free', 'pro', 'team'). */
37
+ planSlug: string;
38
+ /** @untools/pay wallet ID for this team. Set on first billing event. */
39
+ walletId?: string;
40
+ createdAt: Date;
41
+ }
42
+ /** Memberships collection — links a user to a team with a role. */
43
+ export interface MembershipDoc {
44
+ _id: ObjectId;
45
+ teamId: string;
46
+ userId: string;
47
+ role: 'owner' | 'admin' | 'editor' | 'viewer';
48
+ createdAt: Date;
49
+ }
50
+ /** Invites collection — pending email invitations to join a team. */
51
+ export interface InviteDoc {
52
+ _id: ObjectId;
53
+ teamId: string;
54
+ email: string;
55
+ role: 'admin' | 'editor' | 'viewer';
56
+ /** userId of the member who sent the invite. */
57
+ invitedBy: string;
58
+ /** Single-use random token embedded in the invite email link. */
59
+ token: string;
60
+ expiresAt: Date;
61
+ createdAt: Date;
62
+ }
63
+ /** Custom domains collection — maps `content.yoursite.com` to a project. */
64
+ export interface CustomDomainDoc {
65
+ _id: ObjectId;
66
+ projectId: string;
67
+ /** Full hostname, e.g. `content.yoursite.com`. */
68
+ hostname: string;
69
+ /** Cloudflare Custom Hostname ID for SSL provisioning. */
70
+ cfHostnameId?: string;
71
+ /** 'pending' | 'active' | 'error' */
72
+ status: 'pending' | 'active' | 'error';
73
+ createdAt: Date;
74
+ verifiedAt?: Date;
75
+ }
76
+ /**
77
+ * Plans collection — billing plan definitions. Never hard-coded in source.
78
+ * Managed via cloud admin or seeded on deploy.
79
+ */
80
+ export interface PlanDoc {
81
+ _id: ObjectId;
82
+ slug: string;
83
+ displayName: string;
84
+ /** Price in minor units (e.g. kobo, cents). 0 = free. */
85
+ priceMonthly: number;
86
+ currency: string;
87
+ /** Numeric limits. -1 = unlimited. Keys match checkLimit() usage. */
88
+ limits: Record<string, number>;
89
+ /** Feature flags/values. Keys match checkFeature() usage. */
90
+ features: Record<string, boolean | number>;
91
+ isActive: boolean;
92
+ createdAt: Date;
93
+ }
94
+ /**
95
+ * Embed tokens collection — short-lived, origin-restricted tokens issued to
96
+ * allow embedding a project's editor in an iframe or Web Component.
97
+ * Stored so they can be revoked before expiry.
98
+ */
99
+ export interface EmbedTokenDoc {
100
+ _id: ObjectId;
101
+ projectId: string;
102
+ /** SHA-256 hash of the plaintext embed token. */
103
+ tokenHash: string;
104
+ allowedOrigin: string;
105
+ expiresAt: Date;
106
+ createdAt: Date;
107
+ /** userId who issued the token. */
108
+ issuedBy: string;
109
+ }
110
+ /**
111
+ * Audit event record persisted by `withAuditLog` when a MongoDB persister
112
+ * is configured. Mirrors the `AuditEvent` shape from `@airdraft/core`.
113
+ */
114
+ export interface AuditEventDoc {
115
+ _id: ObjectId;
116
+ projectId: string;
117
+ requestId: string;
118
+ timestamp: string;
119
+ durationMs: number;
120
+ method: string;
121
+ path: string;
122
+ action: string;
123
+ collection?: string;
124
+ slug?: string;
125
+ statusCode: number;
126
+ actor?: string;
127
+ request?: Record<string, unknown>;
128
+ response?: Record<string, unknown>;
129
+ error?: {
130
+ message: string;
131
+ code?: string;
132
+ };
133
+ }
134
+ /**
135
+ * Typed handle to all Airdraft Cloud MongoDB collections.
136
+ * Obtained via `createCloudDb()`.
137
+ */
138
+ export interface CloudDb {
139
+ projects: Collection<ProjectDoc>;
140
+ teams: Collection<TeamDoc>;
141
+ memberships: Collection<MembershipDoc>;
142
+ invites: Collection<InviteDoc>;
143
+ plans: Collection<PlanDoc>;
144
+ customDomains: Collection<CustomDomainDoc>;
145
+ embedTokens: Collection<EmbedTokenDoc>;
146
+ /** Audit events persisted by the CMS runtime audit log plugin. */
147
+ auditEvents: Collection<AuditEventDoc>;
148
+ }
149
+ /**
150
+ * Pluggable token cache for GitHub installation access tokens.
151
+ * The default production implementation uses Upstash Redis (HTTP REST).
152
+ * Any object implementing this interface can be used (in-memory, Redis, etc.).
153
+ *
154
+ * Cache keys follow the pattern `github:token:{installationId}`.
155
+ */
156
+ export interface TokenCache {
157
+ get(key: string): Promise<string | null>;
158
+ set(key: string, value: string, ttlSeconds: number): Promise<void>;
159
+ del(key: string): Promise<void>;
160
+ }
161
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAMnD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAA;IACtB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,IAAI,CAAA;IACjB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,QAAQ,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,kFAAkF;IAClF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,2CAA2C;IAC3C,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,0EAA0E;AAC1E,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,QAAQ,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAA;IAChB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,QAAQ,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAA;IAC7C,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,QAAQ,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACnC,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,QAAQ,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAA;IAChB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qCAAqC;IACrC,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;IACtC,SAAS,EAAE,IAAI,CAAA;IACf,UAAU,CAAC,EAAE,IAAI,CAAA;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,QAAQ,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAA;IAC1C,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,IAAI,CAAA;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,QAAQ,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;IACf,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,QAAQ,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3C;AAMD;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,CAAA;IAChC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;IACtC,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IAC9B,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,aAAa,EAAE,UAAU,CAAC,eAAe,CAAC,CAAA;IAC1C,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;IACtC,kEAAkE;IAClE,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;CACvC;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAChC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import type { CloudDb, TokenCache } from './types.js';
2
+ export interface WebhookOptions {
3
+ /** `GITHUB_APP_WEBHOOK_SECRET` env var. */
4
+ webhookSecret: string;
5
+ db: CloudDb;
6
+ /** Optional L2 cache — used to invalidate cached tokens and schemas on uninstall. */
7
+ cache?: TokenCache;
8
+ /**
9
+ * Derives the Redis key for a project's schema cache.
10
+ * Default: `schema:{projectId}`
11
+ */
12
+ schemaCacheKey?: (projectId: string) => string;
13
+ }
14
+ /**
15
+ * Handler for `POST /github/webhook`.
16
+ *
17
+ * Handles the GitHub App webhook events Airdraft cares about:
18
+ * - `installation.deleted` — disconnects the project, invalidates token + schema caches
19
+ * - `installation_repositories` — future: update accessible repo list
20
+ * - `push` — invalidates schema cache when `airdraft.config.json` changes
21
+ *
22
+ * ```ts
23
+ * export async function POST(req: Request) {
24
+ * return handleWebhook(req, { webhookSecret: process.env.GITHUB_WEBHOOK_SECRET!, db, cache })
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function handleWebhook(req: Request, opts: WebhookOptions): Promise<Response>;
29
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAMrD,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAA;IACrB,EAAE,EAAE,OAAO,CAAA;IACX,qFAAqF;IACrF,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/C;AA2DD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,QAAQ,CAAC,CA+FnB"}
@@ -0,0 +1,125 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ import { bustEngineCache } from './runtime.js';
3
+ // ---------------------------------------------------------------------------
4
+ // Helpers
5
+ // ---------------------------------------------------------------------------
6
+ const TOKEN_CACHE_KEY = (installationId) => `github:token:${installationId}`;
7
+ const DEFAULT_SCHEMA_KEY = (projectId) => `schema:${projectId}`;
8
+ function json(body, status = 200) {
9
+ return new Response(JSON.stringify(body), {
10
+ status,
11
+ headers: { 'Content-Type': 'application/json' },
12
+ });
13
+ }
14
+ /**
15
+ * Verifies a GitHub webhook HMAC-SHA256 signature.
16
+ * Returns false if the header is missing or the signature doesn't match.
17
+ */
18
+ async function verifyWebhookSignature(body, signatureHeader, secret) {
19
+ if (!signatureHeader?.startsWith('sha256='))
20
+ return false;
21
+ const expected = 'sha256=' + createHmac('sha256', secret).update(body).digest('hex');
22
+ const expectedBuf = Buffer.from(expected);
23
+ const receivedBuf = Buffer.from(signatureHeader);
24
+ if (expectedBuf.length !== receivedBuf.length)
25
+ return false;
26
+ return timingSafeEqual(expectedBuf, receivedBuf);
27
+ }
28
+ // ---------------------------------------------------------------------------
29
+ // handleWebhook
30
+ // ---------------------------------------------------------------------------
31
+ /**
32
+ * Handler for `POST /github/webhook`.
33
+ *
34
+ * Handles the GitHub App webhook events Airdraft cares about:
35
+ * - `installation.deleted` — disconnects the project, invalidates token + schema caches
36
+ * - `installation_repositories` — future: update accessible repo list
37
+ * - `push` — invalidates schema cache when `airdraft.config.json` changes
38
+ *
39
+ * ```ts
40
+ * export async function POST(req: Request) {
41
+ * return handleWebhook(req, { webhookSecret: process.env.GITHUB_WEBHOOK_SECRET!, db, cache })
42
+ * }
43
+ * ```
44
+ */
45
+ export async function handleWebhook(req, opts) {
46
+ const body = await req.text();
47
+ const signature = req.headers.get('X-Hub-Signature-256');
48
+ const event = req.headers.get('X-GitHub-Event');
49
+ // Verify signature — invalid → 401
50
+ const valid = await verifyWebhookSignature(body, signature, opts.webhookSecret);
51
+ if (!valid) {
52
+ return json({ error: 'INVALID_SIGNATURE' }, 401);
53
+ }
54
+ let payload;
55
+ try {
56
+ payload = JSON.parse(body);
57
+ }
58
+ catch {
59
+ return json({ error: 'INVALID_PAYLOAD' }, 400);
60
+ }
61
+ const schemaCacheKey = opts.schemaCacheKey ?? DEFAULT_SCHEMA_KEY;
62
+ // -------------------------------------------------------------------------
63
+ // installation.deleted — disconnect project, bust caches
64
+ // -------------------------------------------------------------------------
65
+ if (event === 'installation') {
66
+ const { action, installation } = payload;
67
+ if (action === 'deleted') {
68
+ const installationId = installation.id;
69
+ // Find all projects with this installationId
70
+ const projects = await opts.db.projects
71
+ .find({ 'github.installationId': installationId })
72
+ .toArray();
73
+ if (projects.length > 0) {
74
+ // Disconnect all matching projects
75
+ await opts.db.projects.updateMany({ 'github.installationId': installationId }, { $set: { github: null, updatedAt: new Date() } });
76
+ // Invalidate caches
77
+ if (opts.cache) {
78
+ await opts.cache.del(TOKEN_CACHE_KEY(installationId));
79
+ for (const p of projects) {
80
+ await opts.cache.del(schemaCacheKey(p._id.toString()));
81
+ }
82
+ }
83
+ }
84
+ }
85
+ // installation.created → no-op (connection is written in callback, not here)
86
+ return json({ ok: true });
87
+ }
88
+ // -------------------------------------------------------------------------
89
+ // push — invalidate schema cache if airdraft.config.json changed
90
+ // -------------------------------------------------------------------------
91
+ if (event === 'push') {
92
+ const push = payload;
93
+ const changedFiles = push.commits.flatMap((c) => [
94
+ ...c.added,
95
+ ...c.removed,
96
+ ...c.modified,
97
+ ]);
98
+ const schemaChanged = changedFiles.includes('airdraft.schema.json') ||
99
+ changedFiles.includes('airdraft.config.json');
100
+ if (schemaChanged) {
101
+ const repo = push.repository.full_name;
102
+ // Find all projects connected to this repo
103
+ const projects = await opts.db.projects.find({ 'github.repo': repo }).toArray();
104
+ for (const p of projects) {
105
+ // Bust Redis schema cache
106
+ if (opts.cache) {
107
+ await opts.cache.del(schemaCacheKey(p._id.toString()));
108
+ }
109
+ // Bust in-memory engine cache for immediate next-request refresh
110
+ bustEngineCache(p._id.toString());
111
+ }
112
+ }
113
+ return json({ ok: true });
114
+ }
115
+ // -------------------------------------------------------------------------
116
+ // installation_repositories — future: update stored accessible repos list
117
+ // -------------------------------------------------------------------------
118
+ if (event === 'installation_repositories') {
119
+ // Currently no persistent accessible-repo list — re-queried on demand
120
+ return json({ ok: true });
121
+ }
122
+ // Unknown event — acknowledge with 200 (GitHub retries on non-2xx)
123
+ return json({ ok: true });
124
+ }
125
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@airdraft/cloud",
3
+ "version": "0.1.0",
4
+ "description": "Airdraft Cloud — MongoDB schemas, GitHub App handlers (relay, callback, webhook)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": ["dist", "README.md", "CHANGELOG.md"],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "clean": "rm -rf dist",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest",
21
+ "typecheck": "tsc --noEmit",
22
+ "prepublishOnly": "npm run build",
23
+ "release": "standard-version",
24
+ "release:patch": "standard-version --release-as patch",
25
+ "release:minor": "standard-version --release-as minor",
26
+ "release:major": "standard-version --release-as major"
27
+ },
28
+ "publishConfig": { "access": "public" },
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "@airdraft/auth": "*",
32
+ "@airdraft/cloud-auth": "*",
33
+ "@airdraft/core": "*",
34
+ "@airdraft/next": "*",
35
+ "@airdraft/plugin-auth": "*",
36
+ "mongodb": "^6.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.0.0",
40
+ "standard-version": "^9.5.0",
41
+ "typescript": "^5.4.0",
42
+ "vitest": "^1.5.0"
43
+ },
44
+ "engines": { "node": ">=18.0.0" }
45
+ }