@molecule/api-git-provider-smolforge 1.0.2

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.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ <!--
2
+ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
+ Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
+ Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
+ To change this document, edit the module-level JSDoc in src/index.ts.
6
+ Generated: 2026-08-07T00:19:27.110Z
7
+ -->
8
+
9
+ # @molecule/api-git-provider-smolforge
10
+
11
+ > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
12
+ > It is written to be read by coding agents as much as by people, and is generated from this
13
+ > package's source — edit `src/index.ts` JSDoc, not this file.
14
+
15
+ `@molecule/api-git-provider-smolforge` — a `@molecule/api-git-provider` bond.
16
+
17
+ Register it with `registerGitProvider(provider)` in `setupBonds()`; the app
18
+ then never names this host. See the core package for the interface and for
19
+ why `basicAuthUsername` may be null.
20
+
21
+ ## Quick Start
22
+
23
+ ```typescript
24
+ import { registerGitProvider } from '@molecule/api-git-provider'
25
+ import { provider } from '@molecule/api-git-provider-smolforge'
26
+
27
+ registerGitProvider(provider)
28
+ ```
29
+
30
+ ## Type
31
+
32
+ `provider`
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ npm install @molecule/api-git-provider-smolforge @molecule/api-git-provider @molecule/api-http
38
+ ```
39
+
40
+ ## API
41
+
42
+ ### Constants
43
+
44
+ #### `provider`
45
+
46
+ The SmolForge provider.
47
+
48
+ The first bond in this category with no OAuth: SmolForge's
49
+ `GET /api/auth/login-options` reports a single `password` method, and there
50
+ are no authorize/token endpoints. Git access is via a personal access token
51
+ the user mints, which is why `auth.kind` is `pat`.
52
+
53
+ ```typescript
54
+ const provider: GitProvider
55
+ ```
56
+
57
+ ## Core Interface
58
+
59
+ Implements `@molecule/api-git-provider` interface.
60
+
61
+ ## Bond Wiring
62
+
63
+ Setup function to register this provider with the core interface:
64
+
65
+ ```typescript
66
+ import { registerGitProvider } from '@molecule/api-git-provider'
67
+ import { provider } from '@molecule/api-git-provider-smolforge'
68
+
69
+ export function setupGitProviderSmolforge(): void {
70
+ registerGitProvider(provider)
71
+ }
72
+ ```
73
+
74
+ ## Injection Notes
75
+
76
+ ### Requirements
77
+
78
+ Peer dependencies:
79
+
80
+ - `@molecule/api-git-provider` ^1.0.2
81
+ - `@molecule/api-http` ^1.0.1
82
+
83
+ ### Runtime Dependencies
84
+
85
+ - `@molecule/api-git-provider`
86
+ - `@molecule/api-http`
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `@molecule/api-git-provider-smolforge` — a `@molecule/api-git-provider` bond.
3
+ *
4
+ * Register it with `registerGitProvider(provider)` in `setupBonds()`; the app
5
+ * then never names this host. See the core package for the interface and for
6
+ * why `basicAuthUsername` may be null.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { registerGitProvider } from '@molecule/api-git-provider'
11
+ * import { provider } from '@molecule/api-git-provider-smolforge'
12
+ *
13
+ * registerGitProvider(provider)
14
+ * ```
15
+ *
16
+ * @module
17
+ */
18
+ export * from './provider.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,cAAc,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `@molecule/api-git-provider-smolforge` — a `@molecule/api-git-provider` bond.
3
+ *
4
+ * Register it with `registerGitProvider(provider)` in `setupBonds()`; the app
5
+ * then never names this host. See the core package for the interface and for
6
+ * why `basicAuthUsername` may be null.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { registerGitProvider } from '@molecule/api-git-provider'
11
+ * import { provider } from '@molecule/api-git-provider-smolforge'
12
+ *
13
+ * registerGitProvider(provider)
14
+ * ```
15
+ *
16
+ * @module
17
+ */
18
+ export * from './provider.js';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * SmolForge git-hosting provider.
3
+ *
4
+ * @module
5
+ */
6
+ import type { GitProvider } from '@molecule/api-git-provider';
7
+ /**
8
+ * The SmolForge provider.
9
+ *
10
+ * The first bond in this category with no OAuth: SmolForge's
11
+ * `GET /api/auth/login-options` reports a single `password` method, and there
12
+ * are no authorize/token endpoints. Git access is via a personal access token
13
+ * the user mints, which is why `auth.kind` is `pat`.
14
+ */
15
+ export declare const provider: GitProvider;
16
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,WAAW,EAGZ,MAAM,4BAA4B,CAAA;AAqDnC;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,WA8DtB,CAAA"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * SmolForge git-hosting provider.
3
+ *
4
+ * @module
5
+ */
6
+ /**
7
+ * Normalize SmolForge's repository shape.
8
+ *
9
+ * Two fields have to be DERIVED rather than read, because the API does not
10
+ * return them:
11
+ * - `fullName` — composed from `owner.username` and `name`.
12
+ * - `url` — composed as `https://<host>/<owner>/<name>.git`, the documented
13
+ * Git Smart HTTP remote. Every other provider hands back a clone URL.
14
+ *
15
+ * That is why `host` is a parameter here: without it there is no clone URL at
16
+ * all, and emitting a repository a consumer cannot clone is worse than omitting
17
+ * it, since the failure surfaces later during the clone.
18
+ *
19
+ * @param repo - SmolForge's repository JSON.
20
+ * @param host - The instance host, needed to build the clone URL.
21
+ * @returns The normalized repository, or null when unusable.
22
+ */
23
+ const normalize = (repo, host) => {
24
+ const owner = repo.owner?.username;
25
+ if (!owner || !repo.name)
26
+ return null;
27
+ return {
28
+ fullName: `${owner}/${repo.name}`,
29
+ url: `https://${host}/${owner}/${repo.name}.git`,
30
+ private: typeof repo.visibility === 'string' ? repo.visibility !== 'public' : null,
31
+ defaultBranch: repo.default_branch ?? null,
32
+ // Not reported by the API. Null is the honest answer — a 0 would read as an
33
+ // empty repository and could gate an import on a size check that never had
34
+ // real data behind it.
35
+ sizeKb: null,
36
+ updatedAt: repo.updated_at ?? repo.created_at ?? null,
37
+ description: repo.description ?? null,
38
+ };
39
+ };
40
+ /**
41
+ * The SmolForge provider.
42
+ *
43
+ * The first bond in this category with no OAuth: SmolForge's
44
+ * `GET /api/auth/login-options` reports a single `password` method, and there
45
+ * are no authorize/token endpoints. Git access is via a personal access token
46
+ * the user mints, which is why `auth.kind` is `pat`.
47
+ */
48
+ export const provider = {
49
+ id: 'smolforge',
50
+ label: 'SmolForge',
51
+ defaultHost: 'forge.smol.ai',
52
+ auth: {
53
+ kind: 'pat',
54
+ tokensUrl: 'https://forge.smol.ai/settings/tokens',
55
+ },
56
+ // NULL, not a literal: SmolForge expects the user's own Forge username as the
57
+ // basic-auth username, with the PAT as the password. A consumer must
58
+ // substitute the connected account's username here.
59
+ basicAuthUsername: null,
60
+ apiBaseForHost(host) {
61
+ return `https://${host}/api`;
62
+ },
63
+ apiHeaders(token) {
64
+ const headers = {
65
+ 'user-agent': 'molecule-dev',
66
+ accept: 'application/json',
67
+ };
68
+ if (token)
69
+ headers.authorization = `Bearer ${token}`;
70
+ return headers;
71
+ },
72
+ async listRepositories(input) {
73
+ const { get } = await import('@molecule/api-http');
74
+ const base = this.apiBaseForHost(input.host);
75
+ const response = await get(`${base}/repos?per_page=${input.perPage}&page=${input.page}`, { headers: this.apiHeaders(input.token), timeout: 15_000 });
76
+ // Wrapped in `repositories`, unlike the bare arrays GitHub/GitLab/Gitea
77
+ // return — reading `response.data` as an array here yields silently empty
78
+ // pages rather than an error.
79
+ return (response.data?.repositories ?? []).flatMap((repo) => {
80
+ const normalized = normalize(repo, input.host);
81
+ return normalized ? [normalized] : [];
82
+ });
83
+ },
84
+ async getRepository(input) {
85
+ const { get } = await import('@molecule/api-http');
86
+ const base = this.apiBaseForHost(input.host);
87
+ try {
88
+ const response = await get(`${base}/repos/${input.path}`, { headers: this.apiHeaders(input.token), timeout: 15_000 });
89
+ // Single lookups are wrapped too; fall back to the bare object so a shape
90
+ // change in either direction still resolves rather than returning null.
91
+ const repo = response.data?.repository ?? response.data;
92
+ return repo ? normalize(repo, input.host) : null;
93
+ }
94
+ catch (error) {
95
+ const status = error?.response?.status;
96
+ if (status === 404)
97
+ return null;
98
+ throw error;
99
+ }
100
+ },
101
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@molecule/api-git-provider-smolforge",
3
+ "version": "1.0.2",
4
+ "description": "Git hosting provider for SmolForge (forge.smol.ai) — OAuth endpoints, token auth shape, repository listing and lookup.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "test": "vitest run",
11
+ "test:watch": "vitest"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md"
22
+ ],
23
+ "keywords": [
24
+ "molecule",
25
+ "git",
26
+ "provider",
27
+ "smolforge"
28
+ ],
29
+ "license": "Apache-2.0",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/molecule-dev/molecule.git",
33
+ "directory": "packages/api/bonds/git-provider/smolforge"
34
+ },
35
+ "devDependencies": {
36
+ "@molecule/api-git-provider": "1.0.2",
37
+ "@molecule/api-http": "1.0.1",
38
+ "@types/node": "26.1.2",
39
+ "typescript": "6.0.3",
40
+ "vitest": "4.1.10"
41
+ },
42
+ "peerDependencies": {
43
+ "@molecule/api-git-provider": "^1.0.2",
44
+ "@molecule/api-http": "^1.0.1"
45
+ }
46
+ }