@gezelligate/core 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.
- package/LICENSE +21 -0
- package/README.md +29 -0
- package/dist/bridgeManifest.d.ts +67 -0
- package/dist/bridgeManifest.d.ts.map +1 -0
- package/dist/bridgeManifest.js +35 -0
- package/dist/bridgeManifest.js.map +1 -0
- package/dist/capabilities.d.ts +23 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +15 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/catalog/bootstrap.d.ts +25 -0
- package/dist/catalog/bootstrap.d.ts.map +1 -0
- package/dist/catalog/bootstrap.js +56 -0
- package/dist/catalog/bootstrap.js.map +1 -0
- package/dist/catalog/index.d.ts +4 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +4 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/catalog/projectPin.d.ts +22 -0
- package/dist/catalog/projectPin.d.ts.map +1 -0
- package/dist/catalog/projectPin.js +39 -0
- package/dist/catalog/projectPin.js.map +1 -0
- package/dist/catalog/reader.d.ts +44 -0
- package/dist/catalog/reader.d.ts.map +1 -0
- package/dist/catalog/reader.js +7 -0
- package/dist/catalog/reader.js.map +1 -0
- package/dist/catalog/tarball.d.ts +48 -0
- package/dist/catalog/tarball.d.ts.map +1 -0
- package/dist/catalog/tarball.js +114 -0
- package/dist/catalog/tarball.js.map +1 -0
- package/dist/cluster.d.ts +4 -0
- package/dist/cluster.d.ts.map +1 -0
- package/dist/cluster.js +46 -0
- package/dist/cluster.js.map +1 -0
- package/dist/dedicatedPeer.d.ts +43 -0
- package/dist/dedicatedPeer.d.ts.map +1 -0
- package/dist/dedicatedPeer.js +38 -0
- package/dist/dedicatedPeer.js.map +1 -0
- package/dist/dependencies.d.ts +6 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +124 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/ingress.d.ts +4 -0
- package/dist/ingress.d.ts.map +1 -0
- package/dist/ingress.js +17 -0
- package/dist/ingress.js.map +1 -0
- package/dist/keycloak.d.ts +61 -0
- package/dist/keycloak.d.ts.map +1 -0
- package/dist/keycloak.js +161 -0
- package/dist/keycloak.js.map +1 -0
- package/dist/numericId.d.ts +2 -0
- package/dist/numericId.d.ts.map +1 -0
- package/dist/numericId.js +22 -0
- package/dist/numericId.js.map +1 -0
- package/dist/providers/lifecycle.d.ts +81 -0
- package/dist/providers/lifecycle.d.ts.map +1 -0
- package/dist/providers/lifecycle.js +22 -0
- package/dist/providers/lifecycle.js.map +1 -0
- package/dist/providers.d.ts +4 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +45 -0
- package/dist/providers.js.map +1 -0
- package/dist/render.d.ts +22 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +354 -0
- package/dist/render.js.map +1 -0
- package/dist/repository.d.ts +4 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +31 -0
- package/dist/repository.js.map +1 -0
- package/dist/schema/clusterYaml.d.ts +39 -0
- package/dist/schema/clusterYaml.d.ts.map +1 -0
- package/dist/schema/clusterYaml.js +24 -0
- package/dist/schema/clusterYaml.js.map +1 -0
- package/dist/schema/configYaml.d.ts +90 -0
- package/dist/schema/configYaml.d.ts.map +1 -0
- package/dist/schema/configYaml.js +32 -0
- package/dist/schema/configYaml.js.map +1 -0
- package/dist/schema/providerYaml.d.ts +312 -0
- package/dist/schema/providerYaml.d.ts.map +1 -0
- package/dist/schema/providerYaml.js +54 -0
- package/dist/schema/providerYaml.js.map +1 -0
- package/dist/schema/serviceYaml.d.ts +2407 -0
- package/dist/schema/serviceYaml.d.ts.map +1 -0
- package/dist/schema/serviceYaml.js +200 -0
- package/dist/schema/serviceYaml.js.map +1 -0
- package/dist/secrets.d.ts +4 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +31 -0
- package/dist/secrets.js.map +1 -0
- package/dist/secretsSummary.d.ts +2 -0
- package/dist/secretsSummary.d.ts.map +1 -0
- package/dist/secretsSummary.js +50 -0
- package/dist/secretsSummary.js.map +1 -0
- package/dist/services.d.ts +7 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +66 -0
- package/dist/services.js.map +1 -0
- package/dist/sharedDb.d.ts +3 -0
- package/dist/sharedDb.d.ts.map +1 -0
- package/dist/sharedDb.js +104 -0
- package/dist/sharedDb.js.map +1 -0
- package/dist/target.d.ts +35 -0
- package/dist/target.d.ts.map +1 -0
- package/dist/target.js +7 -0
- package/dist/target.js.map +1 -0
- package/dist/templates/dedicated-postgres.docker.yaml.tmpl +12 -0
- package/dist/templates/dedicated-postgres.k8s.yaml.tmpl +57 -0
- package/dist/templates/dedicated-redis.docker.yaml.tmpl +9 -0
- package/dist/templates/dedicated-redis.k8s.yaml.tmpl +46 -0
- package/dist/templating.d.ts +2 -0
- package/dist/templating.d.ts.map +1 -0
- package/dist/templating.js +15 -0
- package/dist/templating.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Spatial Explorers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @gezelligate/core
|
|
2
|
+
|
|
3
|
+
Core engine for [Gezelligate](https://github.com/gezelligate/gezelligate). Schema, loader, templating, validation, target abstraction, and the catalog bootstrap (`bootstrapCatalog`, `TarballCatalogReader`, project pin).
|
|
4
|
+
|
|
5
|
+
This is a library package — most users want [`@gezelligate/studio`](https://www.npmjs.com/package/@gezelligate/studio) or [`@gezelligate/cli`](https://www.npmjs.com/package/@gezelligate/cli). Reach for `core` when you're building your own renderer / target or scripting against the same project shape.
|
|
6
|
+
|
|
7
|
+
## Render with injected targets
|
|
8
|
+
|
|
9
|
+
`core` has no compile-time dependency on `@gezelligate/{docker,k8s}` — callers wire the targets so the package graph stays acyclic.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { render, bootstrapCatalog } from "@gezelligate/core";
|
|
13
|
+
import { renderDockerTarget } from "@gezelligate/docker";
|
|
14
|
+
import { renderKubernetesTarget } from "@gezelligate/k8s";
|
|
15
|
+
|
|
16
|
+
const projectDir = process.cwd();
|
|
17
|
+
const resolved = await bootstrapCatalog({ projectDir });
|
|
18
|
+
|
|
19
|
+
await render({
|
|
20
|
+
projectDir,
|
|
21
|
+
repositoryDir: resolved.recipesDir,
|
|
22
|
+
providersDir: resolved.providersDir,
|
|
23
|
+
targets: { docker: renderDockerTarget, kubernetes: renderKubernetesTarget }
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## License
|
|
28
|
+
|
|
29
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ServiceState } from "./keycloak.js";
|
|
2
|
+
import type { GlobalConfig } from "./schema/configYaml.js";
|
|
3
|
+
export interface BridgeManifestServiceActivity {
|
|
4
|
+
unreadEndpoint: string;
|
|
5
|
+
auth: "oidc-passthrough" | "service-token";
|
|
6
|
+
}
|
|
7
|
+
export interface BridgeManifestServiceRecentItems {
|
|
8
|
+
endpoint: string;
|
|
9
|
+
limit: number;
|
|
10
|
+
mapping: {
|
|
11
|
+
id: string;
|
|
12
|
+
title: string;
|
|
13
|
+
url: string;
|
|
14
|
+
timestamp: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface BridgeManifestServiceSearchApi {
|
|
18
|
+
method: "GET" | "POST";
|
|
19
|
+
endpoint: string;
|
|
20
|
+
body?: string;
|
|
21
|
+
auth: "oidc-passthrough" | "service-token";
|
|
22
|
+
mapping: {
|
|
23
|
+
id: string;
|
|
24
|
+
title: string;
|
|
25
|
+
url: string;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
snippet?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface BridgeManifestServiceSearchIndex {
|
|
31
|
+
table: string;
|
|
32
|
+
where?: string;
|
|
33
|
+
watermark: string;
|
|
34
|
+
fields: {
|
|
35
|
+
id: string;
|
|
36
|
+
title: string;
|
|
37
|
+
body: string;
|
|
38
|
+
url: string;
|
|
39
|
+
timestamp: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface BridgeManifestServiceSearch {
|
|
43
|
+
api?: BridgeManifestServiceSearchApi;
|
|
44
|
+
index?: BridgeManifestServiceSearchIndex;
|
|
45
|
+
}
|
|
46
|
+
export interface BridgeManifestService {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
icon: string;
|
|
50
|
+
url: string;
|
|
51
|
+
activity?: BridgeManifestServiceActivity;
|
|
52
|
+
recentItems?: BridgeManifestServiceRecentItems;
|
|
53
|
+
database?: string;
|
|
54
|
+
search?: BridgeManifestServiceSearch;
|
|
55
|
+
}
|
|
56
|
+
export interface BridgeManifestShare {
|
|
57
|
+
mattermost: {
|
|
58
|
+
enabled: boolean;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export interface BridgeManifest {
|
|
62
|
+
apexDomain: string;
|
|
63
|
+
services: BridgeManifestService[];
|
|
64
|
+
share: BridgeManifestShare;
|
|
65
|
+
}
|
|
66
|
+
export declare function buildBridgeManifest(services: ServiceState[], global: GlobalConfig): BridgeManifest;
|
|
67
|
+
//# sourceMappingURL=bridgeManifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridgeManifest.d.ts","sourceRoot":"","sources":["../src/bridgeManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG3D,MAAM,WAAW,6BAA6B;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,kBAAkB,GAAG,eAAe,CAAC;CAC5C;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,kBAAkB,GAAG,eAAe,CAAC;IAC3C,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1F;AAED,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CACrF;AAED,MAAM,WAAW,2BAA2B;IAC1C,GAAG,CAAC,EAAE,8BAA8B,CAAC;IACrC,KAAK,CAAC,EAAE,gCAAgC,CAAC;CAC1C;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,6BAA6B,CAAC;IACzC,WAAW,CAAC,EAAE,gCAAgC,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EAAE,EACxB,MAAM,EAAE,YAAY,GACnB,cAAc,CA+BhB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { renderTemplate } from "./templating.js";
|
|
2
|
+
export function buildBridgeManifest(services, global) {
|
|
3
|
+
if (global.baseDomain === undefined) {
|
|
4
|
+
throw new Error("buildBridgeManifest requires global.baseDomain to be set");
|
|
5
|
+
}
|
|
6
|
+
const out = [];
|
|
7
|
+
for (const s of services) {
|
|
8
|
+
const bridge = s.def.provides.bridge;
|
|
9
|
+
if (!bridge)
|
|
10
|
+
continue;
|
|
11
|
+
const ctx = { form: s.config.form, global };
|
|
12
|
+
out.push({
|
|
13
|
+
id: s.def.name,
|
|
14
|
+
name: bridge.tile.name,
|
|
15
|
+
icon: bridge.tile.icon,
|
|
16
|
+
url: renderTemplate(bridge.tile.url, ctx),
|
|
17
|
+
activity: bridge.activity ? { ...bridge.activity.api } : undefined,
|
|
18
|
+
recentItems: bridge.recentItems ? { ...bridge.recentItems.api } : undefined,
|
|
19
|
+
database: s.def.database?.preferShared === true ? s.def.database.name : undefined,
|
|
20
|
+
search: bridge.search
|
|
21
|
+
? {
|
|
22
|
+
api: bridge.search.api ? { ...bridge.search.api } : undefined,
|
|
23
|
+
index: bridge.search.index ? { ...bridge.search.index } : undefined
|
|
24
|
+
}
|
|
25
|
+
: undefined
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const mattermostInstalled = services.some(s => s.def.name === "mattermost");
|
|
29
|
+
return {
|
|
30
|
+
apexDomain: global.baseDomain,
|
|
31
|
+
services: out,
|
|
32
|
+
share: { mattermost: { enabled: mattermostInstalled } }
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=bridgeManifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridgeManifest.js","sourceRoot":"","sources":["../src/bridgeManifest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAsDjD,MAAM,UAAU,mBAAmB,CACjC,QAAwB,EACxB,MAAoB;IAEpB,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAC5C,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;YACtB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;YACtB,GAAG,EAAE,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC;YACzC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;YAClE,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;YAC3E,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YACjF,MAAM,EAAE,MAAM,CAAC,MAAM;gBACnB,CAAC,CAAC;oBACE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;oBAC7D,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS;iBACpE;gBACH,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;IACL,CAAC;IACD,MAAM,mBAAmB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IAC5E,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,GAAG;QACb,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,EAAE;KACxD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Provides, ServiceYaml } from "./schema/serviceYaml.js";
|
|
2
|
+
export interface ServiceState {
|
|
3
|
+
def: ServiceYaml;
|
|
4
|
+
env: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export type CapabilityKey = keyof Provides;
|
|
7
|
+
export declare function findOne<S extends {
|
|
8
|
+
def: {
|
|
9
|
+
provides: Provides;
|
|
10
|
+
};
|
|
11
|
+
}>(states: readonly S[], capability: CapabilityKey): S | undefined;
|
|
12
|
+
export declare function findAll<S extends {
|
|
13
|
+
def: {
|
|
14
|
+
provides: Provides;
|
|
15
|
+
};
|
|
16
|
+
}>(states: readonly S[], capability: CapabilityKey): S[];
|
|
17
|
+
export declare function requireOne<S extends {
|
|
18
|
+
def: {
|
|
19
|
+
provides: Provides;
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
}>(states: readonly S[], capability: CapabilityKey, context: string): S;
|
|
23
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAErE,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,WAAW,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC;AAE3C,wBAAgB,OAAO,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAA;CAAE,EAC/D,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,UAAU,EAAE,aAAa,GACxB,CAAC,GAAG,SAAS,CAEf;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAA;CAAE,EAC/D,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,UAAU,EAAE,aAAa,GACxB,CAAC,EAAE,CAEL;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAChF,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,UAAU,EAAE,aAAa,EACzB,OAAO,EAAE,MAAM,GACd,CAAC,CASH"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function findOne(states, capability) {
|
|
2
|
+
return states.find((s) => s.def.provides[capability] !== undefined);
|
|
3
|
+
}
|
|
4
|
+
export function findAll(states, capability) {
|
|
5
|
+
return states.filter((s) => s.def.provides[capability] !== undefined);
|
|
6
|
+
}
|
|
7
|
+
export function requireOne(states, capability, context) {
|
|
8
|
+
const found = findOne(states, capability);
|
|
9
|
+
if (!found) {
|
|
10
|
+
const enabled = states.map((s) => s.def.name).join(", ") || "(none)";
|
|
11
|
+
throw new Error(`No service declares provides.${capability} (needed ${context}). Enabled services: ${enabled}.`);
|
|
12
|
+
}
|
|
13
|
+
return found;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,OAAO,CACrB,MAAoB,EACpB,UAAyB;IAEzB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,MAAoB,EACpB,UAAyB;IAEzB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,MAAoB,EACpB,UAAyB,EACzB,OAAe;IAEf,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,gCAAgC,UAAU,YAAY,OAAO,wBAAwB,OAAO,GAAG,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface BootstrapOptions {
|
|
2
|
+
projectDir: string;
|
|
3
|
+
/** Explicit catalog ref. If omitted, falls back to pin or "latest release". */
|
|
4
|
+
catalogRef?: string;
|
|
5
|
+
/** Explicit local catalog dir. Skips fetching entirely. */
|
|
6
|
+
catalogDir?: string;
|
|
7
|
+
/** GitHub org/user. Defaults to "gezelligate". */
|
|
8
|
+
owner?: string;
|
|
9
|
+
/** GitHub repo. Defaults to "catalog". */
|
|
10
|
+
repo?: string;
|
|
11
|
+
/** Caller's npm version. Recorded in the pin (diagnostic only). */
|
|
12
|
+
callerVersion?: string;
|
|
13
|
+
/** Progress sink. Defaults to writing to stdout. */
|
|
14
|
+
log?: (msg: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface ResolvedCatalog {
|
|
17
|
+
/** Absolute root of the catalog (either a checkout or a fetched cache). */
|
|
18
|
+
catalogDir: string;
|
|
19
|
+
recipesDir: string;
|
|
20
|
+
providersDir: string;
|
|
21
|
+
/** "local" when --catalog-dir is used, otherwise the git ref. */
|
|
22
|
+
ref: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function bootstrapCatalog(opts: BootstrapOptions): Promise<ResolvedCatalog>;
|
|
25
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/catalog/bootstrap.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA4CvF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Shared bootstrap routine used by both CLI (`gezelligate init`) and Studio's
|
|
2
|
+
// first-run hook. Resolves a catalog ref, fetches the tarball if uncached,
|
|
3
|
+
// writes the pin to services/.gezelligate.json, returns the on-disk paths
|
|
4
|
+
// downstream code (renderer, server) needs.
|
|
5
|
+
//
|
|
6
|
+
// Honours three precedence rules:
|
|
7
|
+
// 1. `--catalog-dir` (or programmatic catalogDir) wins outright — treat as a
|
|
8
|
+
// stable local checkout, never fetch, never pin.
|
|
9
|
+
// 2. Explicit `--catalog-ref` overrides what's in the pin file.
|
|
10
|
+
// 3. With neither, an existing pin's ref is reused; on first run, the latest
|
|
11
|
+
// GitHub release is resolved.
|
|
12
|
+
import crypto from "node:crypto";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import { catalogCacheExists, catalogCachePaths, fetchCatalogTarball, projectCatalogDir, resolveLatestCatalogRef } from "./tarball.js";
|
|
15
|
+
import { readProjectPin, writeProjectPin } from "./projectPin.js";
|
|
16
|
+
export async function bootstrapCatalog(opts) {
|
|
17
|
+
const log = opts.log ?? ((m) => process.stdout.write(m));
|
|
18
|
+
if (opts.catalogDir) {
|
|
19
|
+
const catalogDir = path.resolve(opts.catalogDir);
|
|
20
|
+
const paths = catalogCachePaths(catalogDir);
|
|
21
|
+
return {
|
|
22
|
+
catalogDir,
|
|
23
|
+
recipesDir: paths.recipesDir,
|
|
24
|
+
providersDir: paths.providersDir,
|
|
25
|
+
ref: "local"
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const existing = await readProjectPin(opts.projectDir);
|
|
29
|
+
let ref = opts.catalogRef ?? existing?.catalogRef;
|
|
30
|
+
if (!ref) {
|
|
31
|
+
log("→ resolving latest catalog release …\n");
|
|
32
|
+
ref = await resolveLatestCatalogRef({ owner: opts.owner, repo: opts.repo });
|
|
33
|
+
log(` latest release: ${ref}\n`);
|
|
34
|
+
}
|
|
35
|
+
const destDir = projectCatalogDir(opts.projectDir, ref);
|
|
36
|
+
if (!(await catalogCacheExists(opts.projectDir, ref))) {
|
|
37
|
+
const owner = opts.owner ?? "gezelligate";
|
|
38
|
+
const repo = opts.repo ?? "catalog";
|
|
39
|
+
log(`→ fetching catalog ${owner}/${repo}@${ref} …\n`);
|
|
40
|
+
await fetchCatalogTarball({ owner: opts.owner, repo: opts.repo, ref, destDir });
|
|
41
|
+
log(` cached at ${destDir}\n`);
|
|
42
|
+
}
|
|
43
|
+
await writeProjectPin(opts.projectDir, {
|
|
44
|
+
catalogRef: ref,
|
|
45
|
+
projectId: existing?.projectId ?? crypto.randomUUID(),
|
|
46
|
+
...(opts.callerVersion ? { studioVersion: opts.callerVersion } : {})
|
|
47
|
+
});
|
|
48
|
+
const paths = catalogCachePaths(destDir);
|
|
49
|
+
return {
|
|
50
|
+
catalogDir: destDir,
|
|
51
|
+
recipesDir: paths.recipesDir,
|
|
52
|
+
providersDir: paths.providersDir,
|
|
53
|
+
ref
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/catalog/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ProjectPinSchema, type ProjectPin, PIN_RELATIVE_PATH, readProjectPin, writeProjectPin } from "./projectPin.js";
|
|
2
|
+
export { DEFAULT_CATALOG_OWNER, DEFAULT_CATALOG_REPO, type CatalogTarballOptions, type CatalogCachePaths, catalogCachePaths, projectCatalogDir, catalogCacheExists, fetchCatalogTarball, resolveLatestCatalogRef } from "./tarball.js";
|
|
3
|
+
export { type BootstrapOptions, type ResolvedCatalog, bootstrapCatalog } from "./bootstrap.js";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,iBAAiB,EACjB,cAAc,EACd,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ProjectPinSchema, PIN_RELATIVE_PATH, readProjectPin, writeProjectPin } from "./projectPin.js";
|
|
2
|
+
export { DEFAULT_CATALOG_OWNER, DEFAULT_CATALOG_REPO, catalogCachePaths, projectCatalogDir, catalogCacheExists, fetchCatalogTarball, resolveLatestCatalogRef } from "./tarball.js";
|
|
3
|
+
export { bootstrapCatalog } from "./bootstrap.js";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,iBAAiB,EACjB,cAAc,EACd,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EAGpB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAGL,gBAAgB,EACjB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ProjectPinSchema: z.ZodObject<{
|
|
3
|
+
/** Git ref of the gezelligate/catalog repo (release tag preferred, sha allowed). */
|
|
4
|
+
catalogRef: z.ZodString;
|
|
5
|
+
/** Version of @gezelligate/studio (or cli) that initialized this project. Diagnostic only. */
|
|
6
|
+
studioVersion: z.ZodOptional<z.ZodString>;
|
|
7
|
+
/** Stable random uuid per project. Lets the bridge / analytics distinguish projects. */
|
|
8
|
+
projectId: z.ZodString;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
catalogRef: string;
|
|
11
|
+
projectId: string;
|
|
12
|
+
studioVersion?: string | undefined;
|
|
13
|
+
}, {
|
|
14
|
+
catalogRef: string;
|
|
15
|
+
projectId: string;
|
|
16
|
+
studioVersion?: string | undefined;
|
|
17
|
+
}>;
|
|
18
|
+
export type ProjectPin = z.infer<typeof ProjectPinSchema>;
|
|
19
|
+
export declare const PIN_RELATIVE_PATH = "services/.gezelligate.json";
|
|
20
|
+
export declare function readProjectPin(projectDir: string): Promise<ProjectPin | null>;
|
|
21
|
+
export declare function writeProjectPin(projectDir: string, pin: ProjectPin): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=projectPin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectPin.d.ts","sourceRoot":"","sources":["../../src/catalog/projectPin.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;IAC3B,oFAAoF;;IAEpF,8FAA8F;;IAE9F,wFAAwF;;;;;;;;;;EAExF,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,iBAAiB,+BAA+B,CAAC;AAE9D,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAUnF;AAED,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Per-project pin recorded at `services/.gezelligate.json`. Identifies which
|
|
2
|
+
// catalog ref the project was initialized against so subsequent studio/cli
|
|
3
|
+
// runs don't silently upgrade — the user has to opt in via
|
|
4
|
+
// `gezelligate catalog update`.
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
export const ProjectPinSchema = z.object({
|
|
9
|
+
/** Git ref of the gezelligate/catalog repo (release tag preferred, sha allowed). */
|
|
10
|
+
catalogRef: z.string().min(1),
|
|
11
|
+
/** Version of @gezelligate/studio (or cli) that initialized this project. Diagnostic only. */
|
|
12
|
+
studioVersion: z.string().min(1).optional(),
|
|
13
|
+
/** Stable random uuid per project. Lets the bridge / analytics distinguish projects. */
|
|
14
|
+
projectId: z.string().uuid()
|
|
15
|
+
});
|
|
16
|
+
export const PIN_RELATIVE_PATH = "services/.gezelligate.json";
|
|
17
|
+
export async function readProjectPin(projectDir) {
|
|
18
|
+
const pinPath = path.join(projectDir, PIN_RELATIVE_PATH);
|
|
19
|
+
let raw;
|
|
20
|
+
try {
|
|
21
|
+
raw = await fs.readFile(pinPath, "utf8");
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (isNodeErrnoException(err) && err.code === "ENOENT")
|
|
25
|
+
return null;
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
return ProjectPinSchema.parse(JSON.parse(raw));
|
|
29
|
+
}
|
|
30
|
+
export async function writeProjectPin(projectDir, pin) {
|
|
31
|
+
const pinPath = path.join(projectDir, PIN_RELATIVE_PATH);
|
|
32
|
+
await fs.mkdir(path.dirname(pinPath), { recursive: true });
|
|
33
|
+
const validated = ProjectPinSchema.parse(pin);
|
|
34
|
+
await fs.writeFile(pinPath, JSON.stringify(validated, null, 2) + "\n", "utf8");
|
|
35
|
+
}
|
|
36
|
+
function isNodeErrnoException(err) {
|
|
37
|
+
return err instanceof Error && "code" in err;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=projectPin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectPin.js","sourceRoot":"","sources":["../../src/catalog/projectPin.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,2DAA2D;AAC3D,gCAAgC;AAEhC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,oFAAoF;IACpF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,8FAA8F;IAC9F,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC3C,wFAAwF;IACxF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;CAC7B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACzD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,oBAAoB,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACpE,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAAkB,EAAE,GAAe;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACzD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAY;IACxC,OAAO,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ServiceYaml } from "../schema/serviceYaml.js";
|
|
2
|
+
import type { ProviderYaml } from "../schema/providerYaml.js";
|
|
3
|
+
export interface RecipeMeta {
|
|
4
|
+
name: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
category: string;
|
|
7
|
+
description: string;
|
|
8
|
+
required: boolean;
|
|
9
|
+
hidden?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ProviderMeta {
|
|
12
|
+
name: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CatalogIndex {
|
|
16
|
+
recipes: RecipeMeta[];
|
|
17
|
+
providers: ProviderMeta[];
|
|
18
|
+
/** Catalog ref (git tag or sha) this index was generated from. */
|
|
19
|
+
ref: string;
|
|
20
|
+
/** ISO timestamp of catalog generation. */
|
|
21
|
+
generatedAt: string;
|
|
22
|
+
}
|
|
23
|
+
/** Templates + manifest for a single recipe, ready to render. */
|
|
24
|
+
export interface RecipeBundle {
|
|
25
|
+
manifest: ServiceYaml;
|
|
26
|
+
/** Map of template-path → contents (e.g. "values.yaml.tmpl" → "..."). */
|
|
27
|
+
templates: Map<string, string>;
|
|
28
|
+
/** Optional per-recipe assets (e.g. icon.svg). */
|
|
29
|
+
assets?: Map<string, string>;
|
|
30
|
+
}
|
|
31
|
+
export interface ProviderBundle {
|
|
32
|
+
manifest: ProviderYaml;
|
|
33
|
+
templates: Map<string, string>;
|
|
34
|
+
/** Path to the lifecycle.ts module, suitable for dynamic import. */
|
|
35
|
+
lifecycleModulePath: string;
|
|
36
|
+
}
|
|
37
|
+
export interface CatalogReader {
|
|
38
|
+
index(): Promise<CatalogIndex>;
|
|
39
|
+
listRecipes(): Promise<RecipeMeta[]>;
|
|
40
|
+
listProviders(): Promise<ProviderMeta[]>;
|
|
41
|
+
recipe(name: string): Promise<RecipeBundle>;
|
|
42
|
+
provider(name: string): Promise<ProviderBundle>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/catalog/reader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,iEAAiE;AACjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,CAAC;IACtB,yEAAyE;IACzE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,kDAAkD;IAClD,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,oEAAoE;IACpE,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACrC,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACjD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// CatalogReader abstraction: a uniform way for studio + cli to read the
|
|
2
|
+
// service-recipe + provider catalog regardless of where it lives (local fs,
|
|
3
|
+
// fetched tarball, lazy fetch). Step 2 introduces the interface only;
|
|
4
|
+
// implementations land in later steps (FsCatalogReader = today's
|
|
5
|
+
// loadRepository + loadProviders, TarballCatalogReader = step 8).
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/catalog/reader.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,4EAA4E;AAC5E,sEAAsE;AACtE,iEAAiE;AACjE,kEAAkE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export declare const DEFAULT_CATALOG_OWNER = "gezelligate";
|
|
2
|
+
export declare const DEFAULT_CATALOG_REPO = "catalog";
|
|
3
|
+
export interface CatalogTarballOptions {
|
|
4
|
+
/** GitHub org/user that owns the catalog repo. Defaults to "gezelligate". */
|
|
5
|
+
owner?: string;
|
|
6
|
+
/** Repo name. Defaults to "catalog". */
|
|
7
|
+
repo?: string;
|
|
8
|
+
/** Git ref — release tag preferred, branch name or sha also accepted. */
|
|
9
|
+
ref: string;
|
|
10
|
+
/** Destination directory. Contents land directly here (strip-components=1). */
|
|
11
|
+
destDir: string;
|
|
12
|
+
}
|
|
13
|
+
/** Path layout inside a fetched catalog cache directory. */
|
|
14
|
+
export interface CatalogCachePaths {
|
|
15
|
+
recipesDir: string;
|
|
16
|
+
providersDir: string;
|
|
17
|
+
indexFile: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function catalogCachePaths(destDir: string): CatalogCachePaths;
|
|
20
|
+
/**
|
|
21
|
+
* Compute the per-project cache directory for a given catalog ref. The Studio
|
|
22
|
+
* and CLI both write through here so the on-disk shape is identical between
|
|
23
|
+
* `init` (CLI) and first-run bootstrap (studio).
|
|
24
|
+
*/
|
|
25
|
+
export declare function projectCatalogDir(projectDir: string, ref: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Returns true if the cache for `ref` is already populated with a recipes/
|
|
28
|
+
* subdir. We treat the presence of `recipes/` as the "fully extracted"
|
|
29
|
+
* marker — any partial fetch would have failed before reaching that step.
|
|
30
|
+
*/
|
|
31
|
+
export declare function catalogCacheExists(projectDir: string, ref: string): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* Fetch a catalog tarball from `https://codeload.github.com/<owner>/<repo>/tar.gz/<ref>`
|
|
34
|
+
* and extract it into `destDir`. Strips the top-level directory codeload
|
|
35
|
+
* inserts so contents land directly in `destDir`. Throws on non-2xx, missing
|
|
36
|
+
* body, or non-zero tar exit.
|
|
37
|
+
*/
|
|
38
|
+
export declare function fetchCatalogTarball(opts: CatalogTarballOptions): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the latest release tag of the catalog repo via GitHub's REST API.
|
|
41
|
+
* Used by `gezelligate init` when the user doesn't pass `--catalog-ref`.
|
|
42
|
+
* Cached in memory by callers; we never write the lookup to disk.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveLatestCatalogRef(opts?: {
|
|
45
|
+
owner?: string;
|
|
46
|
+
repo?: string;
|
|
47
|
+
}): Promise<string>;
|
|
48
|
+
//# sourceMappingURL=tarball.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tarball.d.ts","sourceRoot":"","sources":["../../src/catalog/tarball.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAC;IACZ,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAMpE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ1F;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCpF;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB3G"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Catalog tarball fetcher. Pulls a release of gezelligate/catalog from
|
|
2
|
+
// GitHub's codeload endpoint and extracts it into the per-project cache at
|
|
3
|
+
// `<project>/.gezelligate/catalog/<ref>/`. The destination layout matches
|
|
4
|
+
// the repo layout (recipes/, providers/, catalog.json) so the engine's
|
|
5
|
+
// existing fs-based loaders can read from there directly.
|
|
6
|
+
//
|
|
7
|
+
// We shell out to `tar -xz` rather than depending on a node tar library —
|
|
8
|
+
// tar is present on macOS, Linux, WSL, and Windows 10+. Avoids an npm dep,
|
|
9
|
+
// which matters for studio bundling.
|
|
10
|
+
import fs from "node:fs/promises";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { spawn } from "node:child_process";
|
|
13
|
+
import { Readable } from "node:stream";
|
|
14
|
+
export const DEFAULT_CATALOG_OWNER = "gezelligate";
|
|
15
|
+
export const DEFAULT_CATALOG_REPO = "catalog";
|
|
16
|
+
export function catalogCachePaths(destDir) {
|
|
17
|
+
return {
|
|
18
|
+
recipesDir: path.join(destDir, "recipes"),
|
|
19
|
+
providersDir: path.join(destDir, "providers"),
|
|
20
|
+
indexFile: path.join(destDir, "catalog.json")
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Compute the per-project cache directory for a given catalog ref. The Studio
|
|
25
|
+
* and CLI both write through here so the on-disk shape is identical between
|
|
26
|
+
* `init` (CLI) and first-run bootstrap (studio).
|
|
27
|
+
*/
|
|
28
|
+
export function projectCatalogDir(projectDir, ref) {
|
|
29
|
+
return path.join(projectDir, ".gezelligate", "catalog", ref);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Returns true if the cache for `ref` is already populated with a recipes/
|
|
33
|
+
* subdir. We treat the presence of `recipes/` as the "fully extracted"
|
|
34
|
+
* marker — any partial fetch would have failed before reaching that step.
|
|
35
|
+
*/
|
|
36
|
+
export async function catalogCacheExists(projectDir, ref) {
|
|
37
|
+
const { recipesDir } = catalogCachePaths(projectCatalogDir(projectDir, ref));
|
|
38
|
+
try {
|
|
39
|
+
const stat = await fs.stat(recipesDir);
|
|
40
|
+
return stat.isDirectory();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Fetch a catalog tarball from `https://codeload.github.com/<owner>/<repo>/tar.gz/<ref>`
|
|
48
|
+
* and extract it into `destDir`. Strips the top-level directory codeload
|
|
49
|
+
* inserts so contents land directly in `destDir`. Throws on non-2xx, missing
|
|
50
|
+
* body, or non-zero tar exit.
|
|
51
|
+
*/
|
|
52
|
+
export async function fetchCatalogTarball(opts) {
|
|
53
|
+
const owner = opts.owner ?? DEFAULT_CATALOG_OWNER;
|
|
54
|
+
const repo = opts.repo ?? DEFAULT_CATALOG_REPO;
|
|
55
|
+
const url = `https://codeload.github.com/${owner}/${repo}/tar.gz/${encodeURIComponent(opts.ref)}`;
|
|
56
|
+
const res = await fetch(url);
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
throw new Error(`Catalog fetch failed: GET ${url} → ${res.status} ${res.statusText}`);
|
|
59
|
+
}
|
|
60
|
+
if (!res.body) {
|
|
61
|
+
throw new Error(`Catalog fetch returned no body: ${url}`);
|
|
62
|
+
}
|
|
63
|
+
await fs.mkdir(opts.destDir, { recursive: true });
|
|
64
|
+
await new Promise((resolve, reject) => {
|
|
65
|
+
const tar = spawn("tar", ["-xz", "--strip-components=1", "-C", opts.destDir], {
|
|
66
|
+
stdio: ["pipe", "inherit", "inherit"]
|
|
67
|
+
});
|
|
68
|
+
tar.on("error", (err) => reject(new Error(`tar spawn failed: ${err.message}`)));
|
|
69
|
+
tar.on("close", (code) => {
|
|
70
|
+
if (code === 0)
|
|
71
|
+
resolve();
|
|
72
|
+
else
|
|
73
|
+
reject(new Error(`tar exited with code ${code}`));
|
|
74
|
+
});
|
|
75
|
+
// Node 20+: fetch body is a Web ReadableStream. Convert to Node Readable
|
|
76
|
+
// and pipe into tar's stdin. Cast through `never` to satisfy the strict
|
|
77
|
+
// Node type defs (Readable.fromWeb expects a node:stream/web type).
|
|
78
|
+
const nodeStream = Readable.fromWeb(res.body);
|
|
79
|
+
nodeStream.on("error", reject);
|
|
80
|
+
if (tar.stdin) {
|
|
81
|
+
nodeStream.pipe(tar.stdin);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
reject(new Error("tar child had no stdin"));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the latest release tag of the catalog repo via GitHub's REST API.
|
|
90
|
+
* Used by `gezelligate init` when the user doesn't pass `--catalog-ref`.
|
|
91
|
+
* Cached in memory by callers; we never write the lookup to disk.
|
|
92
|
+
*/
|
|
93
|
+
export async function resolveLatestCatalogRef(opts = {}) {
|
|
94
|
+
const owner = opts.owner ?? DEFAULT_CATALOG_OWNER;
|
|
95
|
+
const repo = opts.repo ?? DEFAULT_CATALOG_REPO;
|
|
96
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/releases/latest`;
|
|
97
|
+
const res = await fetch(url, {
|
|
98
|
+
headers: { Accept: "application/vnd.github+json", "User-Agent": "gezelligate" }
|
|
99
|
+
});
|
|
100
|
+
if (res.status === 404) {
|
|
101
|
+
// No release yet — fall back to main branch HEAD. Useful before v0.1.0
|
|
102
|
+
// is tagged.
|
|
103
|
+
return "main";
|
|
104
|
+
}
|
|
105
|
+
if (!res.ok) {
|
|
106
|
+
throw new Error(`GitHub releases lookup failed: ${res.status} ${res.statusText}`);
|
|
107
|
+
}
|
|
108
|
+
const data = (await res.json());
|
|
109
|
+
if (!data.tag_name) {
|
|
110
|
+
throw new Error(`GitHub releases response missing tag_name: ${url}`);
|
|
111
|
+
}
|
|
112
|
+
return data.tag_name;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=tarball.js.map
|