create-ragen-app 0.6.1 → 0.7.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/README.md +41 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +240 -42
- package/dist/cli.js.map +1 -1
- package/dist/config-template.d.ts.map +1 -1
- package/dist/config-template.js +15 -3
- package/dist/config-template.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/llm-provider.d.ts +2 -0
- package/dist/llm-provider.d.ts.map +1 -1
- package/dist/llm-provider.js +4 -0
- package/dist/llm-provider.js.map +1 -1
- package/dist/manual-setup.d.ts.map +1 -1
- package/dist/manual-setup.js +1 -0
- package/dist/manual-setup.js.map +1 -1
- package/dist/node-version.d.ts +71 -11
- package/dist/node-version.d.ts.map +1 -1
- package/dist/node-version.js +155 -19
- package/dist/node-version.js.map +1 -1
- package/dist/route-table.d.ts +7 -0
- package/dist/route-table.d.ts.map +1 -1
- package/dist/route-table.js +3 -2
- package/dist/route-table.js.map +1 -1
- package/dist/secrets.d.ts +17 -0
- package/dist/secrets.d.ts.map +1 -1
- package/dist/secrets.js +23 -0
- package/dist/secrets.js.map +1 -1
- package/dist/storage-provider.d.ts +88 -3
- package/dist/storage-provider.d.ts.map +1 -1
- package/dist/storage-provider.js +138 -4
- package/dist/storage-provider.js.map +1 -1
- package/dist/tasks.d.ts +138 -11
- package/dist/tasks.d.ts.map +1 -1
- package/dist/tasks.js +196 -19
- package/dist/tasks.js.map +1 -1
- package/package.json +3 -3
|
@@ -13,6 +13,16 @@
|
|
|
13
13
|
* by `tests/architecture/create-ragen-app-knows-the-provider-seams.test.ts` —
|
|
14
14
|
* the same arrangement `manifest.ts` already has with the `.env.example`
|
|
15
15
|
* files.
|
|
16
|
+
*
|
|
17
|
+
* **Three answers, two providers.** The third answer, RustFS, is not a third
|
|
18
|
+
* provider: to the apps it is plain S3 on `localhost:59000`, and the seam has
|
|
19
|
+
* no variant for it and should not grow one. What makes it an answer of its
|
|
20
|
+
* own is everything *around* the app config — it is a service this install
|
|
21
|
+
* starts (compose's `s3` profile), and the store's keys have to be known to
|
|
22
|
+
* two files that are read by two different programs: Compose reads `.env` to
|
|
23
|
+
* give RustFS its keys, the apps read `.env.local` to present them. So a
|
|
24
|
+
* selection carries `composeProfiles` and `composeEnv` beside `envUpdates`,
|
|
25
|
+
* and `provider` stays what the config and the seam understand.
|
|
16
26
|
*/
|
|
17
27
|
/**
|
|
18
28
|
* One field of a written config, and the variable it resolves from.
|
|
@@ -28,7 +38,50 @@ export interface ConfigField {
|
|
|
28
38
|
envVar: string;
|
|
29
39
|
required: boolean;
|
|
30
40
|
}
|
|
31
|
-
|
|
41
|
+
/** What the wizard offers. */
|
|
42
|
+
export type StorageChoice = 'local' | 's3' | 'rustfs';
|
|
43
|
+
/**
|
|
44
|
+
* What the app sees — `STORAGE_PROVIDER` and `ragen.config.ts`'s `provider`.
|
|
45
|
+
* Kept separate from `StorageChoice` so that `'rustfs'` cannot reach either:
|
|
46
|
+
* the seam would refuse it at boot, and the typed config would not compile.
|
|
47
|
+
*/
|
|
48
|
+
export type StorageProvider = 'local' | 's3';
|
|
49
|
+
/** The compose profile RustFS and its two init containers sit behind. */
|
|
50
|
+
export declare const RUSTFS_COMPOSE_PROFILE = "s3";
|
|
51
|
+
/**
|
|
52
|
+
* Where the apps reach RustFS. The apps run on the host (compose runs only the
|
|
53
|
+
* backing services), so this is the published port, not `rustfs:9000` — that
|
|
54
|
+
* name resolves only inside the compose network. The defaults mirror
|
|
55
|
+
* `docker-compose.yml`, and `RUSTFS_PUBLISHED_PORTS` in `tasks.ts` is held to
|
|
56
|
+
* that file by `installer-ports-agree-with-compose.test.ts`.
|
|
57
|
+
*/
|
|
58
|
+
export declare const RUSTFS_ENDPOINT_URL = "http://localhost:59000";
|
|
59
|
+
/**
|
|
60
|
+
* Where RustFS answers from *inside* the compose network — for the apps when
|
|
61
|
+
* they run as containers (`npm run ragen:up:everything`), where `localhost` is
|
|
62
|
+
* the container itself. `docker-compose.fullapp.yml` prefers
|
|
63
|
+
* `S3_CONTAINER_ENDPOINT_URL` over `S3_ENDPOINT_URL` for exactly this.
|
|
64
|
+
*/
|
|
65
|
+
export declare const RUSTFS_CONTAINER_ENDPOINT_URL = "http://rustfs:9000";
|
|
66
|
+
/** The web console, printed at the end so someone can look inside the store. */
|
|
67
|
+
export declare const RUSTFS_CONSOLE_URL = "http://localhost:59001";
|
|
68
|
+
/** The bucket `rustfs-bucket-init` creates on every `up`. */
|
|
69
|
+
export declare const RUSTFS_BUCKET = "ragen";
|
|
70
|
+
/**
|
|
71
|
+
* RustFS ignores the region, but the AWS SDK refuses to sign a request without
|
|
72
|
+
* one and the seam requires `S3_REGION`. `us-east-1` is what every
|
|
73
|
+
* S3-compatible server answers to, and what the bucket init uses.
|
|
74
|
+
*/
|
|
75
|
+
export declare const RUSTFS_REGION = "us-east-1";
|
|
76
|
+
/**
|
|
77
|
+
* The keys RustFS is started with. Generated per install rather than using
|
|
78
|
+
* compose's `ragen-local` defaults, which are printed in a public file.
|
|
79
|
+
*/
|
|
80
|
+
export interface RustfsKeys {
|
|
81
|
+
accessKey: string;
|
|
82
|
+
secretKey: string;
|
|
83
|
+
}
|
|
84
|
+
export declare function generateRustfsKeys(): RustfsKeys;
|
|
32
85
|
export interface S3Answers {
|
|
33
86
|
bucket: string;
|
|
34
87
|
region: string;
|
|
@@ -38,12 +91,44 @@ export interface S3Answers {
|
|
|
38
91
|
endpoint: string;
|
|
39
92
|
}
|
|
40
93
|
export interface StorageSelection {
|
|
41
|
-
|
|
94
|
+
/** The answer, so later steps can tell RustFS from an S3 someone else runs. */
|
|
95
|
+
choice: StorageChoice;
|
|
96
|
+
provider: StorageProvider;
|
|
42
97
|
/** Written to the root `.env.local` — credentials never go in the config. */
|
|
43
98
|
envUpdates: Record<string, string>;
|
|
44
99
|
/** The config fields, already named as the config names them. */
|
|
45
100
|
configFields: ConfigField[];
|
|
101
|
+
/** Passed to `docker compose --profile …`, so choosing it starts it. */
|
|
102
|
+
composeProfiles: string[];
|
|
103
|
+
/**
|
|
104
|
+
* Lines for the install's `.env`, which Compose reads and the apps do not.
|
|
105
|
+
* Written only where the file has no value yet — see `writeComposeEnv` in
|
|
106
|
+
* `cli.ts` for why an existing value wins.
|
|
107
|
+
*/
|
|
108
|
+
composeEnv: Record<string, string>;
|
|
46
109
|
}
|
|
47
110
|
export declare const STORAGE_LABELS: Record<StorageChoice, string>;
|
|
48
|
-
|
|
111
|
+
/**
|
|
112
|
+
* `answers` is read for `s3`, `rustfsKeys` for `rustfs`. RustFS generates its
|
|
113
|
+
* keys when none are given; the wizard passes them only when the install's
|
|
114
|
+
* `.env` already holds keys the store was started with (see
|
|
115
|
+
* `withExistingRustfsKeys`).
|
|
116
|
+
*/
|
|
117
|
+
export declare function resolveStorageSelection(choice: StorageChoice, answers?: S3Answers, rustfsKeys?: RustfsKeys): StorageSelection;
|
|
118
|
+
/**
|
|
119
|
+
* The same selection, with any RustFS key the install's `.env` already has
|
|
120
|
+
* taking the place of the generated one.
|
|
121
|
+
*
|
|
122
|
+
* `.env` wins because it is what the store was *started* with: RustFS takes
|
|
123
|
+
* its root keys from its environment on every boot, and rotating them in
|
|
124
|
+
* `.env.local` alone would leave the apps presenting keys the running store
|
|
125
|
+
* does not know. Rotating both would be worse on a store that already holds
|
|
126
|
+
* files — the new keys would work, and nothing would say the old ones were
|
|
127
|
+
* someone's only record. Reusing them keeps `.env` and `.env.local` agreeing,
|
|
128
|
+
* which is the invariant that matters: one pair of keys, written twice.
|
|
129
|
+
*
|
|
130
|
+
* Per key, not all-or-nothing, because the `.env` merge is per line too: a
|
|
131
|
+
* file with only one of the two keeps it and gets the other appended.
|
|
132
|
+
*/
|
|
133
|
+
export declare function withExistingRustfsKeys(selection: StorageSelection, existing: Record<string, string | undefined>): StorageSelection;
|
|
49
134
|
//# sourceMappingURL=storage-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-provider.d.ts","sourceRoot":"","sources":["../src/storage-provider.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"storage-provider.d.ts","sourceRoot":"","sources":["../src/storage-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,8BAA8B;AAC9B,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,IAAI,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,uBAAuB,CAAC;AAElE,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,2BAA2B,CAAC;AAE3D,6DAA6D;AAC7D,eAAO,MAAM,aAAa,UAAU,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,IAAI,UAAU,CAK/C;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,eAAe,CAAC;IAC1B,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,iEAAiE;IACjE,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,wEAAwE;IACxE,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAIxD,CAAC;AAkBF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,SAAS,EACnB,UAAU,CAAC,EAAE,UAAU,GACtB,gBAAgB,CAmBlB;AA4CD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC3C,gBAAgB,CAalB"}
|
package/dist/storage-provider.js
CHANGED
|
@@ -14,13 +14,60 @@
|
|
|
14
14
|
* by `tests/architecture/create-ragen-app-knows-the-provider-seams.test.ts` —
|
|
15
15
|
* the same arrangement `manifest.ts` already has with the `.env.example`
|
|
16
16
|
* files.
|
|
17
|
+
*
|
|
18
|
+
* **Three answers, two providers.** The third answer, RustFS, is not a third
|
|
19
|
+
* provider: to the apps it is plain S3 on `localhost:59000`, and the seam has
|
|
20
|
+
* no variant for it and should not grow one. What makes it an answer of its
|
|
21
|
+
* own is everything *around* the app config — it is a service this install
|
|
22
|
+
* starts (compose's `s3` profile), and the store's keys have to be known to
|
|
23
|
+
* two files that are read by two different programs: Compose reads `.env` to
|
|
24
|
+
* give RustFS its keys, the apps read `.env.local` to present them. So a
|
|
25
|
+
* selection carries `composeProfiles` and `composeEnv` beside `envUpdates`,
|
|
26
|
+
* and `provider` stays what the config and the seam understand.
|
|
17
27
|
*/
|
|
18
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.STORAGE_LABELS = void 0;
|
|
29
|
+
exports.STORAGE_LABELS = exports.RUSTFS_REGION = exports.RUSTFS_BUCKET = exports.RUSTFS_CONSOLE_URL = exports.RUSTFS_CONTAINER_ENDPOINT_URL = exports.RUSTFS_ENDPOINT_URL = exports.RUSTFS_COMPOSE_PROFILE = void 0;
|
|
30
|
+
exports.generateRustfsKeys = generateRustfsKeys;
|
|
20
31
|
exports.resolveStorageSelection = resolveStorageSelection;
|
|
32
|
+
exports.withExistingRustfsKeys = withExistingRustfsKeys;
|
|
33
|
+
const secrets_1 = require("./secrets");
|
|
34
|
+
/** The compose profile RustFS and its two init containers sit behind. */
|
|
35
|
+
exports.RUSTFS_COMPOSE_PROFILE = 's3';
|
|
36
|
+
/**
|
|
37
|
+
* Where the apps reach RustFS. The apps run on the host (compose runs only the
|
|
38
|
+
* backing services), so this is the published port, not `rustfs:9000` — that
|
|
39
|
+
* name resolves only inside the compose network. The defaults mirror
|
|
40
|
+
* `docker-compose.yml`, and `RUSTFS_PUBLISHED_PORTS` in `tasks.ts` is held to
|
|
41
|
+
* that file by `installer-ports-agree-with-compose.test.ts`.
|
|
42
|
+
*/
|
|
43
|
+
exports.RUSTFS_ENDPOINT_URL = 'http://localhost:59000';
|
|
44
|
+
/**
|
|
45
|
+
* Where RustFS answers from *inside* the compose network — for the apps when
|
|
46
|
+
* they run as containers (`npm run ragen:up:everything`), where `localhost` is
|
|
47
|
+
* the container itself. `docker-compose.fullapp.yml` prefers
|
|
48
|
+
* `S3_CONTAINER_ENDPOINT_URL` over `S3_ENDPOINT_URL` for exactly this.
|
|
49
|
+
*/
|
|
50
|
+
exports.RUSTFS_CONTAINER_ENDPOINT_URL = 'http://rustfs:9000';
|
|
51
|
+
/** The web console, printed at the end so someone can look inside the store. */
|
|
52
|
+
exports.RUSTFS_CONSOLE_URL = 'http://localhost:59001';
|
|
53
|
+
/** The bucket `rustfs-bucket-init` creates on every `up`. */
|
|
54
|
+
exports.RUSTFS_BUCKET = 'ragen';
|
|
55
|
+
/**
|
|
56
|
+
* RustFS ignores the region, but the AWS SDK refuses to sign a request without
|
|
57
|
+
* one and the seam requires `S3_REGION`. `us-east-1` is what every
|
|
58
|
+
* S3-compatible server answers to, and what the bucket init uses.
|
|
59
|
+
*/
|
|
60
|
+
exports.RUSTFS_REGION = 'us-east-1';
|
|
61
|
+
function generateRustfsKeys() {
|
|
62
|
+
return {
|
|
63
|
+
accessKey: (0, secrets_1.generateS3AccessKeyId)(),
|
|
64
|
+
secretKey: (0, secrets_1.generateS3SecretAccessKey)(),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
21
67
|
exports.STORAGE_LABELS = {
|
|
22
68
|
local: 'Local filesystem (default — no cloud account needed)',
|
|
23
69
|
s3: 'S3-compatible (AWS, Cloudflare R2, Scaleway, MinIO, Ceph)',
|
|
70
|
+
rustfs: 'RustFS — self-hosted object storage, started with the stack',
|
|
24
71
|
};
|
|
25
72
|
/**
|
|
26
73
|
* A path-style endpoint is what Scaleway (dotted bucket names) and MinIO/Ceph
|
|
@@ -35,16 +82,96 @@ function needsPathStyle(endpoint) {
|
|
|
35
82
|
return (!host.includes('amazonaws.com') &&
|
|
36
83
|
!host.includes('r2.cloudflarestorage.com'));
|
|
37
84
|
}
|
|
38
|
-
|
|
39
|
-
|
|
85
|
+
/**
|
|
86
|
+
* `answers` is read for `s3`, `rustfsKeys` for `rustfs`. RustFS generates its
|
|
87
|
+
* keys when none are given; the wizard passes them only when the install's
|
|
88
|
+
* `.env` already holds keys the store was started with (see
|
|
89
|
+
* `withExistingRustfsKeys`).
|
|
90
|
+
*/
|
|
91
|
+
function resolveStorageSelection(choice, answers, rustfsKeys) {
|
|
92
|
+
if (choice === 'rustfs') {
|
|
93
|
+
return rustfsSelection(rustfsKeys ?? generateRustfsKeys());
|
|
94
|
+
}
|
|
95
|
+
if (choice === 'local' || !answers) {
|
|
40
96
|
return {
|
|
97
|
+
choice: 'local',
|
|
41
98
|
provider: 'local',
|
|
42
99
|
envUpdates: { STORAGE_PROVIDER: 'local' },
|
|
43
100
|
configFields: [
|
|
44
101
|
{ field: 'path', envVar: 'STORAGE_LOCAL_PATH', required: false },
|
|
45
102
|
],
|
|
103
|
+
composeProfiles: [],
|
|
104
|
+
composeEnv: {},
|
|
46
105
|
};
|
|
47
106
|
}
|
|
107
|
+
return s3Selection(answers);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* RustFS through the S3 path, not beside it: the same five variables and the
|
|
111
|
+
* same config fields an S3 answer pointed at `localhost:59000` would produce.
|
|
112
|
+
* A second hand-written list is how the two would drift, and the apps cannot
|
|
113
|
+
* tell them apart anyway. Path-style comes from `needsPathStyle` like it does
|
|
114
|
+
* for MinIO — a `localhost` host has no bucket subdomains to resolve.
|
|
115
|
+
*/
|
|
116
|
+
function rustfsSelection(keys) {
|
|
117
|
+
const s3 = s3Selection({
|
|
118
|
+
bucket: exports.RUSTFS_BUCKET,
|
|
119
|
+
region: exports.RUSTFS_REGION,
|
|
120
|
+
endpoint: exports.RUSTFS_ENDPOINT_URL,
|
|
121
|
+
accessKeyId: keys.accessKey,
|
|
122
|
+
secretAccessKey: keys.secretKey,
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
...s3,
|
|
126
|
+
choice: 'rustfs',
|
|
127
|
+
composeProfiles: [exports.RUSTFS_COMPOSE_PROFILE],
|
|
128
|
+
// `.env` is the only file Compose reads, and it serves two readers: the
|
|
129
|
+
// RustFS server (its root keys) and, with the apps in containers
|
|
130
|
+
// (`ragen:up:everything`), the apps themselves — which otherwise never see
|
|
131
|
+
// `.env.local` and would quietly store to the local volume instead. So the
|
|
132
|
+
// S3 settings go here too, derived from the same pair of keys, with the
|
|
133
|
+
// container-side endpoint. The host apps are unaffected: `.env.local`
|
|
134
|
+
// holds the same values and wins over `.env`, and nothing on the host
|
|
135
|
+
// reads S3_CONTAINER_ENDPOINT_URL.
|
|
136
|
+
composeEnv: {
|
|
137
|
+
RUSTFS_ACCESS_KEY: keys.accessKey,
|
|
138
|
+
RUSTFS_SECRET_KEY: keys.secretKey,
|
|
139
|
+
STORAGE_PROVIDER: 's3',
|
|
140
|
+
S3_CONTAINER_ENDPOINT_URL: exports.RUSTFS_CONTAINER_ENDPOINT_URL,
|
|
141
|
+
S3_FORCE_PATH_STYLE: 'true',
|
|
142
|
+
S3_REGION: exports.RUSTFS_REGION,
|
|
143
|
+
S3_BUCKET_NAME: exports.RUSTFS_BUCKET,
|
|
144
|
+
S3_ACCESS_KEY_ID: keys.accessKey,
|
|
145
|
+
S3_SECRET_ACCESS_KEY: keys.secretKey,
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The same selection, with any RustFS key the install's `.env` already has
|
|
151
|
+
* taking the place of the generated one.
|
|
152
|
+
*
|
|
153
|
+
* `.env` wins because it is what the store was *started* with: RustFS takes
|
|
154
|
+
* its root keys from its environment on every boot, and rotating them in
|
|
155
|
+
* `.env.local` alone would leave the apps presenting keys the running store
|
|
156
|
+
* does not know. Rotating both would be worse on a store that already holds
|
|
157
|
+
* files — the new keys would work, and nothing would say the old ones were
|
|
158
|
+
* someone's only record. Reusing them keeps `.env` and `.env.local` agreeing,
|
|
159
|
+
* which is the invariant that matters: one pair of keys, written twice.
|
|
160
|
+
*
|
|
161
|
+
* Per key, not all-or-nothing, because the `.env` merge is per line too: a
|
|
162
|
+
* file with only one of the two keeps it and gets the other appended.
|
|
163
|
+
*/
|
|
164
|
+
function withExistingRustfsKeys(selection, existing) {
|
|
165
|
+
if (selection.choice !== 'rustfs') {
|
|
166
|
+
return selection;
|
|
167
|
+
}
|
|
168
|
+
const accessKey = existing.RUSTFS_ACCESS_KEY?.trim() ||
|
|
169
|
+
selection.composeEnv.RUSTFS_ACCESS_KEY;
|
|
170
|
+
const secretKey = existing.RUSTFS_SECRET_KEY?.trim() ||
|
|
171
|
+
selection.composeEnv.RUSTFS_SECRET_KEY;
|
|
172
|
+
return rustfsSelection({ accessKey, secretKey });
|
|
173
|
+
}
|
|
174
|
+
function s3Selection(answers) {
|
|
48
175
|
const endpoint = answers.endpoint.trim();
|
|
49
176
|
const envUpdates = {
|
|
50
177
|
STORAGE_PROVIDER: 's3',
|
|
@@ -79,6 +206,13 @@ function resolveStorageSelection(provider, answers) {
|
|
|
79
206
|
});
|
|
80
207
|
}
|
|
81
208
|
}
|
|
82
|
-
return {
|
|
209
|
+
return {
|
|
210
|
+
choice: 's3',
|
|
211
|
+
provider: 's3',
|
|
212
|
+
envUpdates,
|
|
213
|
+
configFields,
|
|
214
|
+
composeProfiles: [],
|
|
215
|
+
composeEnv: {},
|
|
216
|
+
};
|
|
83
217
|
}
|
|
84
218
|
//# sourceMappingURL=storage-provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-provider.js","sourceRoot":"","sources":["../src/storage-provider.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"storage-provider.js","sourceRoot":"","sources":["../src/storage-provider.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;AAuEH,gDAKC;AAyDD,0DAuBC;AA2DD,wDAgBC;AAtND,uCAA6E;AAY7E,yEAAyE;AAC5D,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAE3C;;;;;;GAMG;AACU,QAAA,mBAAmB,GAAG,wBAAwB,CAAC;AAE5D;;;;;GAKG;AACU,QAAA,6BAA6B,GAAG,oBAAoB,CAAC;AAElE,gFAAgF;AACnE,QAAA,kBAAkB,GAAG,wBAAwB,CAAC;AAE3D,6DAA6D;AAChD,QAAA,aAAa,GAAG,OAAO,CAAC;AAErC;;;;GAIG;AACU,QAAA,aAAa,GAAG,WAAW,CAAC;AAWzC,SAAgB,kBAAkB;IAChC,OAAO;QACL,SAAS,EAAE,IAAA,+BAAqB,GAAE;QAClC,SAAS,EAAE,IAAA,mCAAyB,GAAE;KACvC,CAAC;AACJ,CAAC;AA6BY,QAAA,cAAc,GAAkC;IAC3D,KAAK,EAAE,sDAAsD;IAC7D,EAAE,EAAE,2DAA2D;IAC/D,MAAM,EAAE,6DAA6D;CACtE,CAAC;AAEF;;;;GAIG;AACH,SAAS,cAAc,CAAC,QAAgB;IACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CACL,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC/B,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAC3C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,uBAAuB,CACrC,MAAqB,EACrB,OAAmB,EACnB,UAAuB;IAEvB,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,eAAe,CAAC,UAAU,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,MAAM,KAAK,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QACnC,OAAO;YACL,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,OAAO;YACjB,UAAU,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE;YACzC,YAAY,EAAE;gBACZ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,QAAQ,EAAE,KAAK,EAAE;aACjE;YACD,eAAe,EAAE,EAAE;YACnB,UAAU,EAAE,EAAE;SACf,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,IAAgB;IACvC,MAAM,EAAE,GAAG,WAAW,CAAC;QACrB,MAAM,EAAE,qBAAa;QACrB,MAAM,EAAE,qBAAa;QACrB,QAAQ,EAAE,2BAAmB;QAC7B,WAAW,EAAE,IAAI,CAAC,SAAS;QAC3B,eAAe,EAAE,IAAI,CAAC,SAAS;KAChC,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,EAAE;QACL,MAAM,EAAE,QAAQ;QAChB,eAAe,EAAE,CAAC,8BAAsB,CAAC;QACzC,wEAAwE;QACxE,iEAAiE;QACjE,2EAA2E;QAC3E,2EAA2E;QAC3E,wEAAwE;QACxE,sEAAsE;QACtE,sEAAsE;QACtE,mCAAmC;QACnC,UAAU,EAAE;YACV,iBAAiB,EAAE,IAAI,CAAC,SAAS;YACjC,iBAAiB,EAAE,IAAI,CAAC,SAAS;YACjC,gBAAgB,EAAE,IAAI;YACtB,yBAAyB,EAAE,qCAA6B;YACxD,mBAAmB,EAAE,MAAM;YAC3B,SAAS,EAAE,qBAAa;YACxB,cAAc,EAAE,qBAAa;YAC7B,gBAAgB,EAAE,IAAI,CAAC,SAAS;YAChC,oBAAoB,EAAE,IAAI,CAAC,SAAS;SACrC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,sBAAsB,CACpC,SAA2B,EAC3B,QAA4C;IAE5C,IAAI,SAAS,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GACb,QAAQ,CAAC,iBAAiB,EAAE,IAAI,EAAE;QAClC,SAAS,CAAC,UAAU,CAAC,iBAAiB,CAAC;IACzC,MAAM,SAAS,GACb,QAAQ,CAAC,iBAAiB,EAAE,IAAI,EAAE;QAClC,SAAS,CAAC,UAAU,CAAC,iBAAiB,CAAC;IAEzC,OAAO,eAAe,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,WAAW,CAAC,OAAkB;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEzC,MAAM,UAAU,GAA2B;QACzC,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;QACrC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;QAChC,gBAAgB,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE;QAC5C,oBAAoB,EAAE,OAAO,CAAC,eAAe,CAAC,IAAI,EAAE;KACrD,CAAC;IAEF,MAAM,YAAY,GAAkB;QAClC,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE;QACjE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE;QACxD,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE;QACpE;YACE,KAAK,EAAE,iBAAiB;YACxB,MAAM,EAAE,sBAAsB;YAC9B,QAAQ,EAAE,IAAI;SACf;KACF,CAAC;IAEF,IAAI,QAAQ,EAAE,CAAC;QACb,UAAU,CAAC,eAAe,GAAG,QAAQ,CAAC;QACtC,YAAY,CAAC,IAAI,CAAC;YAChB,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,iBAAiB;YACzB,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QAEH,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,UAAU,CAAC,mBAAmB,GAAG,MAAM,CAAC;YACxC,YAAY,CAAC,IAAI,CAAC;gBAChB,KAAK,EAAE,gBAAgB;gBACvB,MAAM,EAAE,qBAAqB;gBAC7B,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;QACd,UAAU;QACV,YAAY;QACZ,eAAe,EAAE,EAAE;QACnB,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC"}
|
package/dist/tasks.d.ts
CHANGED
|
@@ -15,26 +15,153 @@ export interface MigrateOptions {
|
|
|
15
15
|
}
|
|
16
16
|
export declare function isDockerAvailable(): Promise<boolean>;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Compose takes its project name from the **directory basename**, which is not
|
|
19
|
+
* the same as being unique per install.
|
|
19
20
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* Removing the pinned `container_name`/volume `name:` from docker-compose.yml
|
|
22
|
+
* scopes every resource to the project, and that is what lets two checkouts
|
|
23
|
+
* coexist. But `/work/a/ragen` and `/work/b/ragen` produce the same project
|
|
24
|
+
* name, and therefore the same containers, volumes and network — the original
|
|
25
|
+
* bug, narrowed to same-named directories rather than fixed. Worse than the
|
|
26
|
+
* port collision, because a *stopped* first stack collides silently: no port
|
|
27
|
+
* is held, nothing refuses, and the second install opens the first one's
|
|
28
|
+
* database.
|
|
26
29
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
+
* So the name is decided here, at install time, and written to the new tree's
|
|
31
|
+
* `.env` — which Compose reads from the project directory on every later
|
|
32
|
+
* `docker compose` the user runs, with no flag to remember. `.env` is the
|
|
33
|
+
* lowest-precedence file `scripts/load-root-env.mjs` reads and is gitignored,
|
|
34
|
+
* and nothing in the apps reads `COMPOSE_PROJECT_NAME`, so it cannot collide
|
|
35
|
+
* with the install's own configuration.
|
|
36
|
+
*
|
|
37
|
+
* The basename is kept whenever it is free, because the readability given up
|
|
38
|
+
* with the pinned names is worth not giving up twice. A suffix appears only
|
|
39
|
+
* when this daemon already runs a project of that name from somewhere else.
|
|
40
|
+
*/
|
|
41
|
+
export interface ComposeProjectName {
|
|
42
|
+
name: string;
|
|
43
|
+
/** True when the plain basename was taken and a suffix was added. */
|
|
44
|
+
disambiguated: boolean;
|
|
45
|
+
/** The compose file of the project that took it, for the message. */
|
|
46
|
+
takenBy?: string;
|
|
47
|
+
/**
|
|
48
|
+
* True when the suffix was added because Docker could not be asked, rather
|
|
49
|
+
* than because a collision was seen. A different sentence to the reader:
|
|
50
|
+
* nothing is wrong, and the name is cautious rather than forced.
|
|
51
|
+
*/
|
|
52
|
+
daemonUnreachable?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Compose accepts `[a-z0-9][a-z0-9_-]*`. A directory called `My Ragen!` or
|
|
56
|
+
* `.ragen` is perfectly legal and would otherwise make every compose command
|
|
57
|
+
* fail with a validation error after the install had finished.
|
|
58
|
+
*/
|
|
59
|
+
export declare function normalizeComposeProjectName(raw: string): string;
|
|
60
|
+
export declare function resolveComposeProjectName(targetDir: string): Promise<ComposeProjectName>;
|
|
61
|
+
/**
|
|
62
|
+
* Every host port a default `docker compose up` publishes, with the variable
|
|
63
|
+
* that moves it. The order is the order the warning prints them in.
|
|
64
|
+
*
|
|
65
|
+
* Defaults are duplicated from docker-compose.yml rather than parsed out of
|
|
66
|
+
* it, because this runs *before* the repository is cloned — there is no file
|
|
67
|
+
* to read yet. `ports-agree-with-compose.test.ts` holds the two in step.
|
|
68
|
+
*/
|
|
69
|
+
export declare const PUBLISHED_PORTS: readonly [{
|
|
70
|
+
readonly service: "Postgres";
|
|
71
|
+
readonly variable: "POSTGRES_PORT";
|
|
72
|
+
readonly port: 55432;
|
|
73
|
+
}, {
|
|
74
|
+
readonly service: "Qdrant";
|
|
75
|
+
readonly variable: "QDRANT_PORT";
|
|
76
|
+
readonly port: 6333;
|
|
77
|
+
}, {
|
|
78
|
+
readonly service: "Qdrant (gRPC)";
|
|
79
|
+
readonly variable: "QDRANT_GRPC_PORT";
|
|
80
|
+
readonly port: 6334;
|
|
81
|
+
}, {
|
|
82
|
+
readonly service: "Docling";
|
|
83
|
+
readonly variable: "DOCLING_PORT";
|
|
84
|
+
readonly port: 5001;
|
|
85
|
+
}, {
|
|
86
|
+
readonly service: "Redis";
|
|
87
|
+
readonly variable: "REDIS_PORT";
|
|
88
|
+
readonly port: 56379;
|
|
89
|
+
}];
|
|
90
|
+
/** The two more, behind the `pii` profile, that only a masking install starts. */
|
|
91
|
+
export declare const PII_PUBLISHED_PORTS: readonly [{
|
|
92
|
+
readonly service: "Presidio analyzer";
|
|
93
|
+
readonly variable: "PRESIDIO_ANALYZER_PORT";
|
|
94
|
+
readonly port: 5002;
|
|
95
|
+
}, {
|
|
96
|
+
readonly service: "Presidio anonymizer";
|
|
97
|
+
readonly variable: "PRESIDIO_ANONYMIZER_PORT";
|
|
98
|
+
readonly port: 5003;
|
|
99
|
+
}];
|
|
100
|
+
/**
|
|
101
|
+
* The two more, behind the `s3` profile, that only a RustFS install starts:
|
|
102
|
+
* the S3 API the apps talk to, and the web console.
|
|
103
|
+
*/
|
|
104
|
+
export declare const RUSTFS_PUBLISHED_PORTS: readonly [{
|
|
105
|
+
readonly service: "RustFS (S3 API)";
|
|
106
|
+
readonly variable: "RUSTFS_PORT";
|
|
107
|
+
readonly port: 59000;
|
|
108
|
+
}, {
|
|
109
|
+
readonly service: "RustFS console";
|
|
110
|
+
readonly variable: "RUSTFS_CONSOLE_PORT";
|
|
111
|
+
readonly port: 59001;
|
|
112
|
+
}];
|
|
113
|
+
export interface PublishedPort {
|
|
114
|
+
service: string;
|
|
115
|
+
variable: string;
|
|
116
|
+
port: number;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The extra ports each optional profile publishes, keyed by profile name.
|
|
120
|
+
*
|
|
121
|
+
* One table rather than a branch per profile, because the port probe, the
|
|
122
|
+
* recovery command and the "update .env.local" hint all have to agree on what
|
|
123
|
+
* a profile starts — and with two profiles the branch-per-profile version was
|
|
124
|
+
* already printing a command that named only one of them.
|
|
125
|
+
*/
|
|
126
|
+
export declare const PROFILE_PUBLISHED_PORTS: Record<string, readonly PublishedPort[]>;
|
|
127
|
+
/** Every port a `docker compose up` with these profiles publishes. */
|
|
128
|
+
export declare function publishedPortsFor(profiles: readonly string[]): PublishedPort[];
|
|
129
|
+
/**
|
|
130
|
+
* The `docker compose up` a person should type to get the stack this install
|
|
131
|
+
* configured, profiles included.
|
|
132
|
+
*
|
|
133
|
+
* Built from the same list `startDockerServices` is given, so a printed
|
|
134
|
+
* command cannot drift from an executed one. A command that drops a profile
|
|
135
|
+
* starts a stack without the services whose URLs were just written to
|
|
136
|
+
* `.env.local` — the half-configuration the profiles exist to prevent, only
|
|
137
|
+
* printed instead of executed.
|
|
138
|
+
*/
|
|
139
|
+
export declare function composeUpCommand(profiles?: readonly string[]): string;
|
|
140
|
+
/**
|
|
141
|
+
* Which of these host ports something is already listening on.
|
|
142
|
+
*
|
|
143
|
+
* This replaces a check for the volume `ragen-postgres-data`. That volume name
|
|
144
|
+
* was pinned in docker-compose.yml, which is what made a second install share
|
|
145
|
+
* the first one's database — and removing the pin removed the sharing, so the
|
|
146
|
+
* old check now answers a question nobody is asking and would answer "clear"
|
|
147
|
+
* for every install made after the change. A guard that quietly stops firing
|
|
148
|
+
* is worse than no guard.
|
|
149
|
+
*
|
|
150
|
+
* Ports are what is genuinely left: Compose prefixes names per project, and
|
|
151
|
+
* prefixes nothing about a published port, so two stacks still collide on
|
|
152
|
+
* 55432. Binding is also a better probe than asking Docker — it sees a native
|
|
153
|
+
* Postgres on the port as well, which is the other way this install ends up
|
|
154
|
+
* talking to a database it did not start.
|
|
30
155
|
*/
|
|
31
|
-
export declare function
|
|
156
|
+
export declare function busyPublishedPorts(candidates?: readonly PublishedPort[]): Promise<PublishedPort[]>;
|
|
32
157
|
/**
|
|
33
158
|
* `profiles` names compose profiles to add to the default set.
|
|
34
159
|
*
|
|
35
160
|
* Without it, choosing PII masking would write the two Presidio URLs and start
|
|
36
161
|
* nothing behind them: those services sit behind compose's `pii` profile, so a
|
|
37
162
|
* plain `up -d` skips them and the app would point at containers nobody ran.
|
|
163
|
+
* RustFS is the same shape behind `s3` — the apps would be configured for an
|
|
164
|
+
* object store on 59000 that nothing started, and fail at the first upload.
|
|
38
165
|
*/
|
|
39
166
|
export declare function startDockerServices({ cwd, profiles, }: RunOptions & {
|
|
40
167
|
profiles?: string[];
|
package/dist/tasks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAU1D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,aAAa,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO/D;AA4BD,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC,CA8C7B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;EAMlB,CAAC;AAEX,kFAAkF;AAClF,eAAO,MAAM,mBAAmB;;;;;;;;EAWtB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;EAOzB,CAAC;AAEX,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAI1E,CAAC;AAEJ,sEAAsE;AACtE,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,aAAa,EAAE,CAKjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAMzE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,GAAE,SAAS,aAAa,EAAoB,GACrD,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAyBD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,GAAG,EACH,QAAa,GACd,EAAE,UAAU,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtD;AAED,wBAAsB,mBAAmB,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAsB,oBAAoB,CAAC,EACzC,GAAG,EACH,GAAG,GACJ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5B;AAED,wBAAsB,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EACxB,EAAE,OAAW,EAAE,YAAmB,EAAE,GAAE,cAAmB,GACxD,OAAO,CAAC,IAAI,CAAC,CAsBf"}
|