t44 0.4.0-rc.3
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/.dco-signatures +9 -0
- package/.github/workflows/dco.yml +12 -0
- package/.o/GordianOpenIntegrity-CurrentLifehash.svg +1026 -0
- package/.o/GordianOpenIntegrity-InceptionLifehash.svg +1026 -0
- package/.o/GordianOpenIntegrity.yaml +25 -0
- package/.o/assets/Hero-Terminal44-v0.jpeg +0 -0
- package/DCO.md +34 -0
- package/LICENSE.md +203 -0
- package/README.md +183 -0
- package/bin/activate +36 -0
- package/bin/activate.ts +30 -0
- package/bin/postinstall.sh +19 -0
- package/bin/shell +27 -0
- package/bin/t44 +27 -0
- package/caps/ConfigSchemaStruct.ts +55 -0
- package/caps/Home.ts +51 -0
- package/caps/HomeRegistry.ts +313 -0
- package/caps/HomeRegistryFile.ts +144 -0
- package/caps/JsonSchemas.ts +220 -0
- package/caps/OpenApiSchema.ts +67 -0
- package/caps/PackageDescriptor.ts +88 -0
- package/caps/ProjectCatalogs.ts +153 -0
- package/caps/ProjectDeployment.ts +363 -0
- package/caps/ProjectDevelopment.ts +257 -0
- package/caps/ProjectPublishing.ts +522 -0
- package/caps/ProjectRack.ts +155 -0
- package/caps/ProjectRepository.ts +322 -0
- package/caps/RootKey.ts +219 -0
- package/caps/SigningKey.ts +243 -0
- package/caps/WorkspaceCli.ts +442 -0
- package/caps/WorkspaceConfig.ts +268 -0
- package/caps/WorkspaceConfig.yaml +71 -0
- package/caps/WorkspaceConfigFile.ts +799 -0
- package/caps/WorkspaceConnection.ts +249 -0
- package/caps/WorkspaceEntityConfig.ts +78 -0
- package/caps/WorkspaceEntityConfig.v0.ts +77 -0
- package/caps/WorkspaceEntityFact.ts +218 -0
- package/caps/WorkspaceInfo.ts +595 -0
- package/caps/WorkspaceInit.ts +30 -0
- package/caps/WorkspaceKey.ts +338 -0
- package/caps/WorkspaceModel.ts +373 -0
- package/caps/WorkspaceProjects.ts +636 -0
- package/caps/WorkspacePrompt.ts +406 -0
- package/caps/WorkspaceShell.sh +39 -0
- package/caps/WorkspaceShell.ts +104 -0
- package/caps/WorkspaceShell.yaml +64 -0
- package/caps/WorkspaceShellCli.ts +109 -0
- package/caps/WorkspaceTest.ts +167 -0
- package/caps/providers/README.md +2 -0
- package/caps/providers/bunny.net/ProjectDeployment.ts +327 -0
- package/caps/providers/bunny.net/api-pull.test.ts +319 -0
- package/caps/providers/bunny.net/api-pull.ts +164 -0
- package/caps/providers/bunny.net/api-storage.test.ts +168 -0
- package/caps/providers/bunny.net/api-storage.ts +248 -0
- package/caps/providers/bunny.net/api.ts +95 -0
- package/caps/providers/dynadot.com/ProjectDeployment.ts +202 -0
- package/caps/providers/dynadot.com/api-domains.test.ts +224 -0
- package/caps/providers/dynadot.com/api-domains.ts +169 -0
- package/caps/providers/dynadot.com/api-restful-v1.test.ts +190 -0
- package/caps/providers/dynadot.com/api-restful-v1.ts +94 -0
- package/caps/providers/dynadot.com/api-restful-v2.test.ts +200 -0
- package/caps/providers/dynadot.com/api-restful-v2.ts +94 -0
- package/caps/providers/git-scm.com/ProjectPublishing.ts +654 -0
- package/caps/providers/github.com/ProjectPublishing.ts +118 -0
- package/caps/providers/github.com/api.ts +115 -0
- package/caps/providers/npmjs.com/ProjectPublishing.ts +536 -0
- package/caps/providers/semver.org/ProjectPublishing.ts +286 -0
- package/caps/providers/vercel.com/ProjectDeployment.ts +326 -0
- package/caps/providers/vercel.com/api.test.ts +67 -0
- package/caps/providers/vercel.com/api.ts +132 -0
- package/caps/providers/vercel.com/bun.lock +194 -0
- package/caps/providers/vercel.com/package.json +10 -0
- package/caps/providers/vercel.com/project.test.ts +108 -0
- package/caps/providers/vercel.com/project.ts +150 -0
- package/caps/providers/vercel.com/tsconfig.json +28 -0
- package/docs/Overview.drawio +248 -0
- package/docs/Overview.svg +4 -0
- package/lib/crypto.ts +53 -0
- package/lib/key.ts +365 -0
- package/lib/schema-console-renderer.ts +181 -0
- package/lib/schema-resolver.ts +349 -0
- package/lib/ucan.ts +137 -0
- package/package.json +101 -0
- package/structs/HomeRegistry.ts +55 -0
- package/structs/HomeRegistryConfig.ts +56 -0
- package/structs/ProjectCatalogsConfig.ts +53 -0
- package/structs/ProjectDeploymentConfig.ts +56 -0
- package/structs/ProjectDeploymentFact.ts +106 -0
- package/structs/ProjectPublishingFact.ts +68 -0
- package/structs/ProjectRack.ts +51 -0
- package/structs/ProjectRackConfig.ts +56 -0
- package/structs/RepositoryOriginDescriptor.ts +51 -0
- package/structs/RootKeyConfig.ts +64 -0
- package/structs/SigningKeyConfig.ts +64 -0
- package/structs/Workspace.ts +56 -0
- package/structs/WorkspaceCatalogs.ts +56 -0
- package/structs/WorkspaceCliConfig.ts +53 -0
- package/structs/WorkspaceConfig.ts +64 -0
- package/structs/WorkspaceConfigFile.ts +50 -0
- package/structs/WorkspaceConfigFileMeta.ts +70 -0
- package/structs/WorkspaceKey.ts +55 -0
- package/structs/WorkspaceKeyConfig.ts +56 -0
- package/structs/WorkspaceMappingsConfig.ts +56 -0
- package/structs/WorkspaceProject.ts +104 -0
- package/structs/WorkspaceProjectsConfig.ts +67 -0
- package/structs/WorkspacePublishingConfig.ts +65 -0
- package/structs/WorkspaceShellConfig.ts +83 -0
- package/structs/providers/README.md +2 -0
- package/structs/providers/bunny.net/PullZoneFact.ts +55 -0
- package/structs/providers/bunny.net/PullZoneListFact.ts +55 -0
- package/structs/providers/bunny.net/StorageZoneFact.ts +55 -0
- package/structs/providers/bunny.net/StorageZoneListFact.ts +55 -0
- package/structs/providers/bunny.net/WorkspaceConnectionConfig.ts +43 -0
- package/structs/providers/dynadot.com/DomainFact.ts +46 -0
- package/structs/providers/dynadot.com/WorkspaceConnectionConfig.ts +54 -0
- package/structs/providers/git-scm.com/ProjectPublishingFact.ts +46 -0
- package/structs/providers/github.com/ProjectPublishingFact.ts +46 -0
- package/structs/providers/github.com/WorkspaceConnectionConfig.ts +43 -0
- package/structs/providers/npmjs.com/ProjectPublishingFact.ts +46 -0
- package/structs/providers/vercel.com/ProjectDeploymentFact.ts +55 -0
- package/structs/providers/vercel.com/WorkspaceConnectionConfig.ts +49 -0
- package/tests/01-Lifecycle/main.test.ts +173 -0
- package/tsconfig.json +28 -0
- package/workspace-rt.ts +134 -0
- package/workspace.yaml +3 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
|
|
4
|
+
export async function capsule({
|
|
5
|
+
encapsulate,
|
|
6
|
+
CapsulePropertyTypes,
|
|
7
|
+
makeImportStack
|
|
8
|
+
}: {
|
|
9
|
+
encapsulate: any
|
|
10
|
+
CapsulePropertyTypes: any
|
|
11
|
+
makeImportStack: any
|
|
12
|
+
}) {
|
|
13
|
+
// Ensures the GitHub repository is provisioned before git-scm pushes to it.
|
|
14
|
+
return encapsulate({
|
|
15
|
+
'#@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0': {
|
|
16
|
+
'#@stream44.studio/encapsulate/structs/Capsule': {},
|
|
17
|
+
'#t44/structs/providers/github.com/ProjectPublishingFact': {
|
|
18
|
+
as: '$GitHubFact'
|
|
19
|
+
},
|
|
20
|
+
'#t44/structs/ProjectPublishingFact': {
|
|
21
|
+
as: '$StatusFact'
|
|
22
|
+
},
|
|
23
|
+
'#': {
|
|
24
|
+
GitHubApi: {
|
|
25
|
+
type: CapsulePropertyTypes.Mapping,
|
|
26
|
+
value: './api'
|
|
27
|
+
},
|
|
28
|
+
ProjectCatalogs: {
|
|
29
|
+
type: CapsulePropertyTypes.Mapping,
|
|
30
|
+
value: 't44/caps/ProjectCatalogs'
|
|
31
|
+
},
|
|
32
|
+
push: {
|
|
33
|
+
type: CapsulePropertyTypes.Function,
|
|
34
|
+
value: async function (this: any, { config }: { config: any }) {
|
|
35
|
+
|
|
36
|
+
const repoSettings = config.provider.config.RepositorySettings
|
|
37
|
+
const owner = repoSettings.owner
|
|
38
|
+
const repo = repoSettings.repo
|
|
39
|
+
const isPrivate = repoSettings.public === true ? false : true
|
|
40
|
+
const description = repoSettings.description || ''
|
|
41
|
+
|
|
42
|
+
console.log(chalk.cyan(`\n🔍 Ensuring GitHub repository '${owner}/${repo}' ...`))
|
|
43
|
+
|
|
44
|
+
const result = await this.GitHubApi.ensureRepo({
|
|
45
|
+
owner,
|
|
46
|
+
repo,
|
|
47
|
+
isPrivate,
|
|
48
|
+
description
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
if (result.created) {
|
|
52
|
+
console.log(chalk.green(` ✓ Repository '${owner}/${repo}' created on GitHub\n`))
|
|
53
|
+
} else {
|
|
54
|
+
console.log(chalk.green(` ✓ Repository '${owner}/${repo}' already exists\n`))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Write provider-specific fact file
|
|
58
|
+
await this.$GitHubFact.set(`${owner}~${repo}`, result.repo)
|
|
59
|
+
|
|
60
|
+
const statusResult = {
|
|
61
|
+
projectName: `${owner}/${repo}`,
|
|
62
|
+
provider: 'github.com',
|
|
63
|
+
status: 'READY',
|
|
64
|
+
publicUrl: result.repo.html_url
|
|
65
|
+
}
|
|
66
|
+
await this.$StatusFact.set(`${owner}~${repo}`, statusResult)
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
afterPush: {
|
|
70
|
+
type: CapsulePropertyTypes.Function,
|
|
71
|
+
value: async function (this: any, { repoName, config }: {
|
|
72
|
+
repoName: string
|
|
73
|
+
config: any
|
|
74
|
+
}): Promise<void> {
|
|
75
|
+
const ghSettings = config.provider.config?.RepositorySettings
|
|
76
|
+
if (!ghSettings) return
|
|
77
|
+
|
|
78
|
+
const owner = ghSettings.owner
|
|
79
|
+
const repo = ghSettings.repo
|
|
80
|
+
|
|
81
|
+
const branches: Record<string, any> = {}
|
|
82
|
+
let isPublic = false
|
|
83
|
+
try {
|
|
84
|
+
const [apiBranches, repoInfo] = await Promise.all([
|
|
85
|
+
this.GitHubApi.listBranches({ owner, repo }),
|
|
86
|
+
this.GitHubApi.getRepo({ owner, repo }),
|
|
87
|
+
])
|
|
88
|
+
for (const b of apiBranches) {
|
|
89
|
+
branches[b.name] = { commit: b.commit }
|
|
90
|
+
}
|
|
91
|
+
if (repoInfo) isPublic = !repoInfo.private
|
|
92
|
+
} catch { }
|
|
93
|
+
|
|
94
|
+
const ghData: Record<string, any> = {
|
|
95
|
+
owner,
|
|
96
|
+
repo,
|
|
97
|
+
public: isPublic,
|
|
98
|
+
repoUrl: `https://github.com/${owner}/${repo}`,
|
|
99
|
+
gitUri: `git@github.com:${owner}/${repo}.git`,
|
|
100
|
+
branches,
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
await this.ProjectCatalogs.updateCatalogRepository({
|
|
104
|
+
repoName,
|
|
105
|
+
providerKey: '#' + capsule['#'],
|
|
106
|
+
providerData: ghData,
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}, {
|
|
113
|
+
importMeta: import.meta,
|
|
114
|
+
importStack: makeImportStack(),
|
|
115
|
+
capsuleName: capsule['#'],
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
capsule['#'] = 't44/caps/providers/github.com/ProjectPublishing'
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
export async function capsule({
|
|
3
|
+
encapsulate,
|
|
4
|
+
CapsulePropertyTypes,
|
|
5
|
+
makeImportStack
|
|
6
|
+
}: {
|
|
7
|
+
encapsulate: any
|
|
8
|
+
CapsulePropertyTypes: any
|
|
9
|
+
makeImportStack: any
|
|
10
|
+
}) {
|
|
11
|
+
// Low level API that maps the GitHub REST API.
|
|
12
|
+
return encapsulate({
|
|
13
|
+
'#@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0': {
|
|
14
|
+
'#@stream44.studio/encapsulate/structs/Capsule': {},
|
|
15
|
+
'#t44/structs/providers/github.com/WorkspaceConnectionConfig': {
|
|
16
|
+
as: '$ConnectionConfig'
|
|
17
|
+
},
|
|
18
|
+
'#': {
|
|
19
|
+
// @see https://docs.github.com/en/rest
|
|
20
|
+
apiHeaders: {
|
|
21
|
+
type: CapsulePropertyTypes.GetterFunction,
|
|
22
|
+
value: async function (this: any) {
|
|
23
|
+
const apiToken = await this.$ConnectionConfig.getConfigValue('apiToken')
|
|
24
|
+
return {
|
|
25
|
+
'Authorization': `Bearer ${apiToken}`,
|
|
26
|
+
'Accept': 'application/vnd.github+json',
|
|
27
|
+
'X-GitHub-Api-Version': '2022-11-28'
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
getRepo: {
|
|
32
|
+
type: CapsulePropertyTypes.Function,
|
|
33
|
+
value: async function (this: any, { owner, repo }: { owner: string, repo: string }) {
|
|
34
|
+
const headers = await this.apiHeaders
|
|
35
|
+
const response = await fetch(`https://api.github.com/repos/${owner}/${repo}`, { headers })
|
|
36
|
+
if (response.status === 404) return null
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
throw new Error(`GitHub API error: ${response.status} ${await response.text()}`)
|
|
39
|
+
}
|
|
40
|
+
return response.json()
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
createRepo: {
|
|
44
|
+
type: CapsulePropertyTypes.Function,
|
|
45
|
+
value: async function (this: any, { org, name, isPrivate, description }: { org?: string, name: string, isPrivate?: boolean, description?: string }) {
|
|
46
|
+
const headers = await this.apiHeaders
|
|
47
|
+
const url = org
|
|
48
|
+
? `https://api.github.com/orgs/${org}/repos`
|
|
49
|
+
: `https://api.github.com/user/repos`
|
|
50
|
+
const response = await fetch(url, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
name,
|
|
55
|
+
private: isPrivate ?? false,
|
|
56
|
+
description: description || '',
|
|
57
|
+
auto_init: false
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
throw new Error(`GitHub API error creating repo: ${response.status} ${await response.text()}`)
|
|
62
|
+
}
|
|
63
|
+
return response.json()
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
listBranches: {
|
|
67
|
+
type: CapsulePropertyTypes.Function,
|
|
68
|
+
value: async function (this: any, { owner, repo }: { owner: string, repo: string }) {
|
|
69
|
+
const headers = await this.apiHeaders
|
|
70
|
+
const branches: Array<{ name: string, commit: string }> = []
|
|
71
|
+
let page = 1
|
|
72
|
+
while (true) {
|
|
73
|
+
const response = await fetch(
|
|
74
|
+
`https://api.github.com/repos/${owner}/${repo}/branches?per_page=100&page=${page}`,
|
|
75
|
+
{ headers }
|
|
76
|
+
)
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new Error(`GitHub API error: ${response.status} ${await response.text()}`)
|
|
79
|
+
}
|
|
80
|
+
const data = await response.json() as any[]
|
|
81
|
+
if (data.length === 0) break
|
|
82
|
+
for (const b of data) {
|
|
83
|
+
branches.push({ name: b.name, commit: b.commit.sha })
|
|
84
|
+
}
|
|
85
|
+
if (data.length < 100) break
|
|
86
|
+
page++
|
|
87
|
+
}
|
|
88
|
+
return branches
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
ensureRepo: {
|
|
92
|
+
type: CapsulePropertyTypes.Function,
|
|
93
|
+
value: async function (this: any, { owner, repo, isPrivate, description }: { owner: string, repo: string, isPrivate?: boolean, description?: string }) {
|
|
94
|
+
const existing = await this.getRepo({ owner, repo })
|
|
95
|
+
if (existing) {
|
|
96
|
+
return { created: false, repo: existing }
|
|
97
|
+
}
|
|
98
|
+
const created = await this.createRepo({
|
|
99
|
+
org: owner,
|
|
100
|
+
name: repo,
|
|
101
|
+
isPrivate,
|
|
102
|
+
description
|
|
103
|
+
})
|
|
104
|
+
return { created: true, repo: created }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}, {
|
|
110
|
+
importMeta: import.meta,
|
|
111
|
+
importStack: makeImportStack(),
|
|
112
|
+
capsuleName: capsule['#'],
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
capsule['#'] = 't44/caps/providers/github.com/api'
|