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.
Files changed (125) hide show
  1. package/.dco-signatures +9 -0
  2. package/.github/workflows/dco.yml +12 -0
  3. package/.o/GordianOpenIntegrity-CurrentLifehash.svg +1026 -0
  4. package/.o/GordianOpenIntegrity-InceptionLifehash.svg +1026 -0
  5. package/.o/GordianOpenIntegrity.yaml +25 -0
  6. package/.o/assets/Hero-Terminal44-v0.jpeg +0 -0
  7. package/DCO.md +34 -0
  8. package/LICENSE.md +203 -0
  9. package/README.md +183 -0
  10. package/bin/activate +36 -0
  11. package/bin/activate.ts +30 -0
  12. package/bin/postinstall.sh +19 -0
  13. package/bin/shell +27 -0
  14. package/bin/t44 +27 -0
  15. package/caps/ConfigSchemaStruct.ts +55 -0
  16. package/caps/Home.ts +51 -0
  17. package/caps/HomeRegistry.ts +313 -0
  18. package/caps/HomeRegistryFile.ts +144 -0
  19. package/caps/JsonSchemas.ts +220 -0
  20. package/caps/OpenApiSchema.ts +67 -0
  21. package/caps/PackageDescriptor.ts +88 -0
  22. package/caps/ProjectCatalogs.ts +153 -0
  23. package/caps/ProjectDeployment.ts +363 -0
  24. package/caps/ProjectDevelopment.ts +257 -0
  25. package/caps/ProjectPublishing.ts +522 -0
  26. package/caps/ProjectRack.ts +155 -0
  27. package/caps/ProjectRepository.ts +322 -0
  28. package/caps/RootKey.ts +219 -0
  29. package/caps/SigningKey.ts +243 -0
  30. package/caps/WorkspaceCli.ts +442 -0
  31. package/caps/WorkspaceConfig.ts +268 -0
  32. package/caps/WorkspaceConfig.yaml +71 -0
  33. package/caps/WorkspaceConfigFile.ts +799 -0
  34. package/caps/WorkspaceConnection.ts +249 -0
  35. package/caps/WorkspaceEntityConfig.ts +78 -0
  36. package/caps/WorkspaceEntityConfig.v0.ts +77 -0
  37. package/caps/WorkspaceEntityFact.ts +218 -0
  38. package/caps/WorkspaceInfo.ts +595 -0
  39. package/caps/WorkspaceInit.ts +30 -0
  40. package/caps/WorkspaceKey.ts +338 -0
  41. package/caps/WorkspaceModel.ts +373 -0
  42. package/caps/WorkspaceProjects.ts +636 -0
  43. package/caps/WorkspacePrompt.ts +406 -0
  44. package/caps/WorkspaceShell.sh +39 -0
  45. package/caps/WorkspaceShell.ts +104 -0
  46. package/caps/WorkspaceShell.yaml +64 -0
  47. package/caps/WorkspaceShellCli.ts +109 -0
  48. package/caps/WorkspaceTest.ts +167 -0
  49. package/caps/providers/README.md +2 -0
  50. package/caps/providers/bunny.net/ProjectDeployment.ts +327 -0
  51. package/caps/providers/bunny.net/api-pull.test.ts +319 -0
  52. package/caps/providers/bunny.net/api-pull.ts +164 -0
  53. package/caps/providers/bunny.net/api-storage.test.ts +168 -0
  54. package/caps/providers/bunny.net/api-storage.ts +248 -0
  55. package/caps/providers/bunny.net/api.ts +95 -0
  56. package/caps/providers/dynadot.com/ProjectDeployment.ts +202 -0
  57. package/caps/providers/dynadot.com/api-domains.test.ts +224 -0
  58. package/caps/providers/dynadot.com/api-domains.ts +169 -0
  59. package/caps/providers/dynadot.com/api-restful-v1.test.ts +190 -0
  60. package/caps/providers/dynadot.com/api-restful-v1.ts +94 -0
  61. package/caps/providers/dynadot.com/api-restful-v2.test.ts +200 -0
  62. package/caps/providers/dynadot.com/api-restful-v2.ts +94 -0
  63. package/caps/providers/git-scm.com/ProjectPublishing.ts +654 -0
  64. package/caps/providers/github.com/ProjectPublishing.ts +118 -0
  65. package/caps/providers/github.com/api.ts +115 -0
  66. package/caps/providers/npmjs.com/ProjectPublishing.ts +536 -0
  67. package/caps/providers/semver.org/ProjectPublishing.ts +286 -0
  68. package/caps/providers/vercel.com/ProjectDeployment.ts +326 -0
  69. package/caps/providers/vercel.com/api.test.ts +67 -0
  70. package/caps/providers/vercel.com/api.ts +132 -0
  71. package/caps/providers/vercel.com/bun.lock +194 -0
  72. package/caps/providers/vercel.com/package.json +10 -0
  73. package/caps/providers/vercel.com/project.test.ts +108 -0
  74. package/caps/providers/vercel.com/project.ts +150 -0
  75. package/caps/providers/vercel.com/tsconfig.json +28 -0
  76. package/docs/Overview.drawio +248 -0
  77. package/docs/Overview.svg +4 -0
  78. package/lib/crypto.ts +53 -0
  79. package/lib/key.ts +365 -0
  80. package/lib/schema-console-renderer.ts +181 -0
  81. package/lib/schema-resolver.ts +349 -0
  82. package/lib/ucan.ts +137 -0
  83. package/package.json +101 -0
  84. package/structs/HomeRegistry.ts +55 -0
  85. package/structs/HomeRegistryConfig.ts +56 -0
  86. package/structs/ProjectCatalogsConfig.ts +53 -0
  87. package/structs/ProjectDeploymentConfig.ts +56 -0
  88. package/structs/ProjectDeploymentFact.ts +106 -0
  89. package/structs/ProjectPublishingFact.ts +68 -0
  90. package/structs/ProjectRack.ts +51 -0
  91. package/structs/ProjectRackConfig.ts +56 -0
  92. package/structs/RepositoryOriginDescriptor.ts +51 -0
  93. package/structs/RootKeyConfig.ts +64 -0
  94. package/structs/SigningKeyConfig.ts +64 -0
  95. package/structs/Workspace.ts +56 -0
  96. package/structs/WorkspaceCatalogs.ts +56 -0
  97. package/structs/WorkspaceCliConfig.ts +53 -0
  98. package/structs/WorkspaceConfig.ts +64 -0
  99. package/structs/WorkspaceConfigFile.ts +50 -0
  100. package/structs/WorkspaceConfigFileMeta.ts +70 -0
  101. package/structs/WorkspaceKey.ts +55 -0
  102. package/structs/WorkspaceKeyConfig.ts +56 -0
  103. package/structs/WorkspaceMappingsConfig.ts +56 -0
  104. package/structs/WorkspaceProject.ts +104 -0
  105. package/structs/WorkspaceProjectsConfig.ts +67 -0
  106. package/structs/WorkspacePublishingConfig.ts +65 -0
  107. package/structs/WorkspaceShellConfig.ts +83 -0
  108. package/structs/providers/README.md +2 -0
  109. package/structs/providers/bunny.net/PullZoneFact.ts +55 -0
  110. package/structs/providers/bunny.net/PullZoneListFact.ts +55 -0
  111. package/structs/providers/bunny.net/StorageZoneFact.ts +55 -0
  112. package/structs/providers/bunny.net/StorageZoneListFact.ts +55 -0
  113. package/structs/providers/bunny.net/WorkspaceConnectionConfig.ts +43 -0
  114. package/structs/providers/dynadot.com/DomainFact.ts +46 -0
  115. package/structs/providers/dynadot.com/WorkspaceConnectionConfig.ts +54 -0
  116. package/structs/providers/git-scm.com/ProjectPublishingFact.ts +46 -0
  117. package/structs/providers/github.com/ProjectPublishingFact.ts +46 -0
  118. package/structs/providers/github.com/WorkspaceConnectionConfig.ts +43 -0
  119. package/structs/providers/npmjs.com/ProjectPublishingFact.ts +46 -0
  120. package/structs/providers/vercel.com/ProjectDeploymentFact.ts +55 -0
  121. package/structs/providers/vercel.com/WorkspaceConnectionConfig.ts +49 -0
  122. package/tests/01-Lifecycle/main.test.ts +173 -0
  123. package/tsconfig.json +28 -0
  124. package/workspace-rt.ts +134 -0
  125. 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'