@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 +86 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/provider.d.ts +16 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +101 -0
- package/package.json +46 -0
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`
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/provider.js
ADDED
|
@@ -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
|
+
}
|