@kitsy/cnos-docs 1.5.1 → 1.6.1
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/docs/api/browser.mdx +2 -0
- package/docs/api/runtime.mdx +13 -0
- package/docs/cli/build.mdx +14 -11
- package/docs/getting-started/quick-start.mdx +7 -0
- package/docs/guides/backend.mdx +17 -2
- package/docs/guides/ci-cd.mdx +18 -2
- package/docs/guides/containers-and-actions.mdx +136 -0
- package/docs/guides/frontend-next.mdx +13 -0
- package/docs/guides/frontend-vite.mdx +14 -0
- package/docs/guides/frontend-webpack.mdx +32 -0
- package/docs/guides/generated-env-files.mdx +2 -0
- package/docs/guides/migration.mdx +108 -7
- package/docs/guides/workspaces.mdx +77 -7
- package/manifest.yml +2 -0
- package/package.json +1 -1
package/docs/api/browser.mdx
CHANGED
|
@@ -14,3 +14,5 @@ console.log(cnos('public.app.apiBaseUrl'));
|
|
|
14
14
|
Only promoted browser-safe values are available here.
|
|
15
15
|
|
|
16
16
|
Framework integrations such as `@kitsy/cnos-vite`, `@kitsy/cnos-next`, and `@kitsy/cnos-webpack` are responsible for embedding that browser payload during the build.
|
|
17
|
+
|
|
18
|
+
The browser runtime does not fetch config over the network. It reads from data already embedded into the bundle/runtime globals by the framework integration, so it follows the same bundle and service-worker caching behavior as the rest of your frontend assets.
|
package/docs/api/runtime.mdx
CHANGED
|
@@ -32,8 +32,12 @@ The runtime currently exposes:
|
|
|
32
32
|
- `cnos.toNamespace(namespace)`
|
|
33
33
|
- `cnos.toEnv()`
|
|
34
34
|
- `cnos.toPublicEnv()`
|
|
35
|
+
- `cnos.toServerProjection()`
|
|
35
36
|
- `cnos.format(message)`
|
|
36
37
|
- `cnos.log(message)`
|
|
38
|
+
- `cnos.loadProjection(path)`
|
|
39
|
+
- `cnos.refreshSecrets()`
|
|
40
|
+
- `cnos.refreshSecret(key)`
|
|
37
41
|
|
|
38
42
|
Example:
|
|
39
43
|
|
|
@@ -54,6 +58,15 @@ cnos.log('Starting server at ${value.server.port}');
|
|
|
54
58
|
|
|
55
59
|
`cnos.format(...)` and `cnos.log(...)` interpolate `${logical.key}` placeholders through the active runtime. Missing keys are left unchanged.
|
|
56
60
|
|
|
61
|
+
For server packaging, the runtime can also bootstrap from a projection artifact:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import cnos from '@kitsy/cnos';
|
|
65
|
+
|
|
66
|
+
await cnos.loadProjection('./.cnos-server.json');
|
|
67
|
+
await cnos.ready();
|
|
68
|
+
```
|
|
69
|
+
|
|
57
70
|
## Typed values
|
|
58
71
|
|
|
59
72
|
CNOS values are not limited to strings. If the underlying config stores numbers, booleans, arrays, or objects, runtime reads return those values as-is.
|
package/docs/cli/build.mdx
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: cnos build
|
|
3
|
-
description: Build
|
|
2
|
+
title: cnos build
|
|
3
|
+
description: Build derived CNOS projection artifacts for server, browser, env, and public surfaces.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# cnos build
|
|
6
|
+
# cnos build
|
|
7
7
|
|
|
8
|
-
Use `build
|
|
8
|
+
Use `build` when a repo needs a deterministic artifact derived from CNOS.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
+
cnos build server --to .cnos-server.json
|
|
12
|
+
cnos build browser --to .cnos-browser.json
|
|
11
13
|
cnos build env --profile local --to .env.local
|
|
12
14
|
cnos build env --profile stage --to .env.stage
|
|
13
|
-
cnos build
|
|
15
|
+
cnos build public --framework vite --to .env.production
|
|
16
|
+
cnos build env --profile local-domain --format docker-env --to .docker/runtime/current.env
|
|
14
17
|
```
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
Targets:
|
|
17
20
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
- writes
|
|
21
|
-
-
|
|
21
|
+
- `build server` writes a server runtime projection with resolved values plus secret refs
|
|
22
|
+
- `build browser` writes a public-only browser projection
|
|
23
|
+
- `build env` writes explicit env mappings in formats like `dotenv`, `shell`, `json`, `yaml`, `docker-env`, or `toml`
|
|
24
|
+
- `build public` writes promoted public env with optional framework prefixes like Vite and Next
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
All build artifacts are derived output. `.cnos` remains the source of truth.
|
|
@@ -45,3 +45,10 @@ For frontend builds:
|
|
|
45
45
|
- Vite: `@kitsy/cnos-vite`
|
|
46
46
|
- Webpack/static bundles: `@kitsy/cnos-webpack`
|
|
47
47
|
- Next.js: `@kitsy/cnos-next`
|
|
48
|
+
|
|
49
|
+
For webpack/static bundles, build-time settings can come from CNOS too:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cnos set value dev.server.port 8800
|
|
53
|
+
npm run dev
|
|
54
|
+
```
|
package/docs/guides/backend.mdx
CHANGED
|
@@ -10,6 +10,15 @@ Backend projects usually use one of two patterns:
|
|
|
10
10
|
- `cnos run -- <command>` for zero-code-change adoption
|
|
11
11
|
- `import cnos from '@kitsy/cnos'` for direct runtime reads
|
|
12
12
|
|
|
13
|
+
For an existing Express or Node service that already uses `.env`, start with the env bridge:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cnos build env --profile local --to .env.local
|
|
17
|
+
cnos build env --profile stage --to .env.stage
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Then keep your current `dotenv` setup while moving runtime reads to CNOS.
|
|
21
|
+
|
|
13
22
|
Example:
|
|
14
23
|
|
|
15
24
|
```ts
|
|
@@ -24,6 +33,12 @@ const token = cnos.secret('app.token');
|
|
|
24
33
|
Env export bridge:
|
|
25
34
|
|
|
26
35
|
```bash
|
|
27
|
-
cnos
|
|
28
|
-
cnos
|
|
36
|
+
cnos build env --to .env.local
|
|
37
|
+
cnos build env --profile stage --to .env.stage
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Projection-first packaging:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cnos build server --profile prod --to .cnos-server.json
|
|
29
44
|
```
|
package/docs/guides/ci-cd.mdx
CHANGED
|
@@ -8,9 +8,10 @@ description: Use CNOS in build and deploy pipelines without committing generated
|
|
|
8
8
|
Common patterns:
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
cnos
|
|
12
|
-
cnos
|
|
11
|
+
cnos build env --profile stage --to .env.stage
|
|
12
|
+
cnos build public --framework vite --profile stage --to .env.stage
|
|
13
13
|
cnos run --profile stage -- pnpm build
|
|
14
|
+
cnos build server --profile prod --to dist/.cnos-server.json
|
|
14
15
|
```
|
|
15
16
|
|
|
16
17
|
For CI-backed vaults:
|
|
@@ -19,3 +20,18 @@ For CI-backed vaults:
|
|
|
19
20
|
cnos vault create github-ci --provider github-secrets --no-passphrase
|
|
20
21
|
cnos secret set app.token APP_TOKEN --vault github-ci
|
|
21
22
|
```
|
|
23
|
+
|
|
24
|
+
GitHub Actions example:
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
- name: Install deps
|
|
28
|
+
run: pnpm install --frozen-lockfile
|
|
29
|
+
|
|
30
|
+
- name: Build CNOS env
|
|
31
|
+
run: cnos build env --profile stage --to .env.stage
|
|
32
|
+
|
|
33
|
+
- name: Build app
|
|
34
|
+
run: pnpm build
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Use `cnos run` when you do not need an intermediate env file. Use `cnos build env` or `cnos build public` when the build tool or deploy step expects a file artifact.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Containers, Kubernetes, and GitHub Actions
|
|
3
|
+
description: Use CNOS-generated artifacts in Docker, Docker Compose, Kubernetes, and GitHub Actions without making .env files the source of truth.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Containers, Kubernetes, and GitHub Actions
|
|
7
|
+
|
|
8
|
+
CNOS should stay the source of truth. Containers and pipelines should consume derived artifacts.
|
|
9
|
+
|
|
10
|
+
Use these patterns:
|
|
11
|
+
|
|
12
|
+
- `cnos build env` when the runtime expects flat env vars
|
|
13
|
+
- `cnos build server` when a server runtime should consume a CNOS projection artifact
|
|
14
|
+
- `cnos run` when a child process should get CNOS directly at launch time
|
|
15
|
+
|
|
16
|
+
## Docker
|
|
17
|
+
|
|
18
|
+
Generate a Docker-friendly env file:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cnos build env --profile local-domain --format docker-env --to .docker/runtime/current.env
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
That file is a derived artifact. Keep it gitignored.
|
|
25
|
+
|
|
26
|
+
For a production-style local preview flow:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm build:local-domain:all
|
|
30
|
+
cnos build env --profile local-domain --format docker-env --to .docker/runtime/current.env
|
|
31
|
+
docker compose up --build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use this when:
|
|
35
|
+
- your image or emulator runtime expects env vars
|
|
36
|
+
- you want one fixed runtime env file per profile
|
|
37
|
+
- the build already consumed the same CNOS profile
|
|
38
|
+
|
|
39
|
+
## Docker Compose
|
|
40
|
+
|
|
41
|
+
Recommended compose pattern:
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
services:
|
|
45
|
+
app:
|
|
46
|
+
env_file:
|
|
47
|
+
- ./.docker/runtime/current.env
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This keeps runtime env injection explicit and lets the same CNOS profile drive:
|
|
51
|
+
- the build step
|
|
52
|
+
- the container runtime
|
|
53
|
+
- local emulators
|
|
54
|
+
|
|
55
|
+
For browser builds behind nginx or another proxy:
|
|
56
|
+
- build the app first with `cnos run --profile <name> -- pnpm build`
|
|
57
|
+
- then feed compose/runtime with `cnos build env --format docker-env`
|
|
58
|
+
|
|
59
|
+
## Kubernetes
|
|
60
|
+
|
|
61
|
+
Use CNOS to render the env payload before applying manifests:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
cnos build env --profile stage --format yaml --to k8s/generated/app-config.yaml
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or generate a flat env file and convert it into a ConfigMap or Secret with your existing tooling:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cnos build env --profile stage --format dotenv --to .artifacts/stage.env
|
|
71
|
+
kubectl create configmap app-config --from-env-file=.artifacts/stage.env --dry-run=client -o yaml
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Rules:
|
|
75
|
+
- do not make Kubernetes manifests the source of truth for application config
|
|
76
|
+
- do not embed decrypted CNOS secret values into build artifacts by default
|
|
77
|
+
- prefer runtime secret providers or platform-native secrets for secret plaintext
|
|
78
|
+
|
|
79
|
+
## GitHub Actions
|
|
80
|
+
|
|
81
|
+
Two good patterns exist.
|
|
82
|
+
|
|
83
|
+
### 1. Build with direct CNOS injection
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
- name: Install deps
|
|
87
|
+
run: pnpm install --frozen-lockfile
|
|
88
|
+
|
|
89
|
+
- name: Build with CNOS
|
|
90
|
+
run: cnos run --profile stage -- pnpm build
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 2. Materialize an env artifact first
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
- name: Build CNOS env file
|
|
97
|
+
run: cnos build env --profile stage --to .env.stage
|
|
98
|
+
|
|
99
|
+
- name: Build app
|
|
100
|
+
run: pnpm build
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
For browser-only frameworks:
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
- name: Build public env for Vite
|
|
107
|
+
run: cnos build public --framework vite --profile stage --to .env.stage
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
For Next:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
- name: Build public env for Next
|
|
114
|
+
run: cnos build public --framework next --profile prod --to .env.production
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For server packaging:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
- name: Build server projection
|
|
121
|
+
run: cnos build server --profile prod --to dist/.cnos-server.json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Secret handling
|
|
125
|
+
|
|
126
|
+
Keep this split clear:
|
|
127
|
+
|
|
128
|
+
- non-secret config can become a build or runtime artifact
|
|
129
|
+
- decrypted secret plaintext should not become a build artifact by default
|
|
130
|
+
|
|
131
|
+
Use:
|
|
132
|
+
- CNOS vault refs
|
|
133
|
+
- platform env injection
|
|
134
|
+
- runtime secret hydration
|
|
135
|
+
|
|
136
|
+
Do not rely on generated env files for secret rotation-sensitive server secrets unless you deliberately accept that tradeoff.
|
|
@@ -5,6 +5,12 @@ description: Use CNOS public projection with Next.js builds and browser-safe run
|
|
|
5
5
|
|
|
6
6
|
# Frontend with Next.js
|
|
7
7
|
|
|
8
|
+
If the app already depends on `NEXT_PUBLIC_*`, keep that contract while CNOS becomes the source of truth:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cnos build public --framework next --profile prod --to .env.production
|
|
12
|
+
```
|
|
13
|
+
|
|
8
14
|
```ts
|
|
9
15
|
import { withCnosNext } from '@kitsy/cnos-next';
|
|
10
16
|
|
|
@@ -12,3 +18,10 @@ export default withCnosNext({});
|
|
|
12
18
|
```
|
|
13
19
|
|
|
14
20
|
Browser-safe values remain under `public.promote` and are exposed as `NEXT_PUBLIC_*` plus browser-runtime data for `@kitsy/cnos/browser`.
|
|
21
|
+
|
|
22
|
+
Migration path:
|
|
23
|
+
|
|
24
|
+
1. keep `NEXT_PUBLIC_*` via generated env or Next env injection
|
|
25
|
+
2. add `withCnosNext()`
|
|
26
|
+
3. move browser-safe reads to `@kitsy/cnos/browser`
|
|
27
|
+
4. move server-only reads to `@kitsy/cnos` or `@kitsy/cnos/configure`
|
|
@@ -5,6 +5,13 @@ description: Project browser-safe CNOS values into Vite and use the browser runt
|
|
|
5
5
|
|
|
6
6
|
# Frontend with Vite
|
|
7
7
|
|
|
8
|
+
If your app already uses `VITE_*`, keep that shape first and let CNOS generate it.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cnos build public --framework vite --profile local --to .env.local
|
|
12
|
+
cnos dev env --public --framework vite --profile local --to .env.local -- pnpm dev
|
|
13
|
+
```
|
|
14
|
+
|
|
8
15
|
Promote browser-safe values:
|
|
9
16
|
|
|
10
17
|
```yaml
|
|
@@ -32,3 +39,10 @@ import cnos from '@kitsy/cnos/browser';
|
|
|
32
39
|
console.log(cnos('public.app.apiBaseUrl'));
|
|
33
40
|
console.log(import.meta.env.VITE_APP_API_BASE_URL);
|
|
34
41
|
```
|
|
42
|
+
|
|
43
|
+
Migration path:
|
|
44
|
+
|
|
45
|
+
1. keep `VITE_*` working through generated env files
|
|
46
|
+
2. add `createCnosVitePlugin()`
|
|
47
|
+
3. move browser reads to `@kitsy/cnos/browser`
|
|
48
|
+
4. stop treating handwritten `.env.local` as the source of truth
|
|
@@ -7,6 +7,26 @@ description: Use CNOS public projection with webpack builds, webpack-dev-server,
|
|
|
7
7
|
|
|
8
8
|
CNOS integrates with webpack through `@kitsy/cnos-webpack`. This covers the common static-bundle case where webpack produces a browser build that is then deployed as static assets.
|
|
9
9
|
|
|
10
|
+
## Highlight: change webpack dev-server config from CNOS
|
|
11
|
+
|
|
12
|
+
Once webpack reads build-time config through `createCnos()`, changing a setting such as the dev-server port is just a config write:
|
|
13
|
+
|
|
14
|
+
```powershell
|
|
15
|
+
cnos set value dev.server.port 8800
|
|
16
|
+
npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Typical result:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
set value.dev.server.port in .cnos\values\dev.yml
|
|
23
|
+
Cnos value.dev.server.port: 8800
|
|
24
|
+
[webpack-dev-server] Project is running at:
|
|
25
|
+
[webpack-dev-server] Loopback: http://localhost:8800/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This is the main benefit of the CNOS webpack path: you change config in `.cnos`, not scattered build scripts or ad hoc env files.
|
|
29
|
+
|
|
10
30
|
Promote browser-safe values:
|
|
11
31
|
|
|
12
32
|
```yaml
|
|
@@ -88,6 +108,18 @@ The webpack plugin:
|
|
|
88
108
|
- keeps server-only `value.*` and `secret.*` out of the browser bundle
|
|
89
109
|
- uses no prefix by default for webpack public env unless you configure `public.frameworks.webpack` or pass `prefix`
|
|
90
110
|
|
|
111
|
+
## Bundle and cache behavior
|
|
112
|
+
|
|
113
|
+
CNOS does not add a runtime fetch layer to the browser bundle.
|
|
114
|
+
|
|
115
|
+
- `@kitsy/cnos-webpack` resolves public config at build time
|
|
116
|
+
- browser-safe values are embedded into the existing webpack bundle through `DefinePlugin` and `globalThis.__CNOS_BROWSER_DATA__`
|
|
117
|
+
- `@kitsy/cnos/browser` is a small reader over that embedded payload
|
|
118
|
+
- if your app does not import `@kitsy/cnos/browser`, webpack can leave it out of the browser bundle
|
|
119
|
+
- if your app does import `@kitsy/cnos/browser`, it is bundled like any other app dependency and follows your existing webpack and service-worker caching strategy
|
|
120
|
+
|
|
121
|
+
So if your site already uses `sw.js` for offline behavior, CNOS does not disable or bypass that. CNOS becomes part of the same built assets your service worker already caches.
|
|
122
|
+
|
|
91
123
|
If you need build-time server config such as `devServer.port`, read it in the webpack config through `createCnos()` so dev and production builds use the same CNOS source of truth.
|
|
92
124
|
|
|
93
125
|
## Plugin order
|
|
@@ -15,6 +15,7 @@ Use generated env files as a **bridge**, not as the source of truth.
|
|
|
15
15
|
cnos build env --profile local --to .env.local
|
|
16
16
|
cnos build env --profile stage --to .env.stage
|
|
17
17
|
cnos build env --profile prod --to .env.prod
|
|
18
|
+
cnos build env --profile local-domain --format docker-env --to .docker/runtime/current.env
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
## Watched dev loop
|
|
@@ -36,3 +37,4 @@ cnos build env --public --framework next --profile prod --to .env.production
|
|
|
36
37
|
- keep generated `.env.*` files gitignored
|
|
37
38
|
- migrate app code toward direct CNOS reads over time
|
|
38
39
|
- keep secrets on runtime/vault flows instead of materializing them into env files by default
|
|
40
|
+
- use `docker-env` when Docker or Docker Compose expects a runtime env file
|
|
@@ -5,7 +5,16 @@ description: Move existing env-based projects onto CNOS without losing current w
|
|
|
5
5
|
|
|
6
6
|
# Migrating from .env
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
CNOS migration works best as a bridge, not a flag day.
|
|
9
|
+
|
|
10
|
+
The pattern is:
|
|
11
|
+
|
|
12
|
+
1. Keep `.cnos` as the new source of truth.
|
|
13
|
+
2. Keep your current app/build/runtime working.
|
|
14
|
+
3. Generate whatever bridge artifact the existing stack needs.
|
|
15
|
+
4. Migrate direct env reads to CNOS app by app.
|
|
16
|
+
|
|
17
|
+
Use the migration assistant when you want help mapping existing env usage:
|
|
9
18
|
|
|
10
19
|
```bash
|
|
11
20
|
cnos migrate --scan src --dry-run
|
|
@@ -13,20 +22,112 @@ cnos migrate --apply
|
|
|
13
22
|
cnos migrate --apply --rewrite
|
|
14
23
|
```
|
|
15
24
|
|
|
16
|
-
|
|
25
|
+
## Plain Node or Express with `.env`
|
|
26
|
+
|
|
27
|
+
If your service currently starts with `dotenv`, keep that flow first.
|
|
17
28
|
|
|
18
29
|
```bash
|
|
19
|
-
cnos build env --to .env.local
|
|
30
|
+
cnos build env --profile local --to .env.local
|
|
20
31
|
cnos build env --profile stage --to .env.stage
|
|
21
|
-
cnos dev env --profile local --to .env.local -- pnpm dev
|
|
22
32
|
```
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
Then your existing `dotenv` bootstrap keeps working.
|
|
35
|
+
|
|
36
|
+
Move server code gradually:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import cnos from '@kitsy/cnos';
|
|
40
|
+
|
|
41
|
+
await cnos.ready();
|
|
42
|
+
|
|
43
|
+
const port = cnos.readOr('value.server.port', 3000);
|
|
44
|
+
const token = cnos.secret('app.token');
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
For runtime packaging instead of env files:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cnos build server --profile prod --to .cnos-server.json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Vite Frontend
|
|
54
|
+
|
|
55
|
+
If you already use `VITE_*` env variables, keep that contract first.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cnos build public --framework vite --profile local --to .env.local
|
|
59
|
+
cnos dev env --public --framework vite --profile local --to .env.local -- pnpm dev
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Then add `@kitsy/cnos-vite` and migrate browser reads to:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import cnos from '@kitsy/cnos/browser';
|
|
66
|
+
|
|
67
|
+
cnos('public.app.apiBaseUrl');
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Next.js
|
|
71
|
+
|
|
72
|
+
If you already use `NEXT_PUBLIC_*`, keep that contract while adopting CNOS.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cnos build public --framework next --profile prod --to .env.production
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Then wire `@kitsy/cnos-next` so Next gets public data from CNOS directly and browser code can read `public.*` through `@kitsy/cnos/browser`.
|
|
79
|
+
|
|
80
|
+
## Webpack Static Frontend
|
|
81
|
+
|
|
82
|
+
If you already have a `webpack.config.js`, you do not need to invent a new runtime.
|
|
83
|
+
|
|
84
|
+
- read build-time settings such as dev-server port through `createCnos()`
|
|
85
|
+
- inject browser-safe config through `@kitsy/cnos-webpack`
|
|
86
|
+
- keep generated `.env.*` files only if your repo still expects them
|
|
87
|
+
|
|
88
|
+
Example bridge:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cnos build public --profile local --to .env.local
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Longer-term path:
|
|
95
|
+
|
|
96
|
+
- `CnosWebpackPlugin` for browser-safe values
|
|
97
|
+
- `createCnos()` inside webpack config for build-time settings
|
|
98
|
+
|
|
99
|
+
## pnpm Monorepo
|
|
100
|
+
|
|
101
|
+
For monorepos, do not copy `.cnos` into every package.
|
|
102
|
+
|
|
103
|
+
- keep one repo-root `.cnos/`
|
|
104
|
+
- add `.cnosrc.yml` to each consuming app/package
|
|
105
|
+
- optionally add a repo-root `.cnosrc.yml` if the root also consumes CNOS
|
|
106
|
+
|
|
107
|
+
Example:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
# apps/travel/.cnosrc.yml
|
|
111
|
+
root: ../../.cnos
|
|
112
|
+
workspace: travel
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Server-side packages can use projections:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cnos build server --workspace travel --profile prod --to apps/travel/.cnos-server.json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Legacy env-based packages can still use:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
cnos build env --workspace travel --profile local --to apps/travel/.env.local
|
|
125
|
+
```
|
|
25
126
|
|
|
26
127
|
Recommended migration sequence:
|
|
27
128
|
|
|
28
129
|
1. Keep `.cnos` as the source of truth.
|
|
29
|
-
2. Generate `.env
|
|
130
|
+
2. Generate `.env.*`, browser, or server projection artifacts for legacy tools.
|
|
30
131
|
3. Migrate server code to `@kitsy/cnos`.
|
|
31
132
|
4. Migrate browser code to `@kitsy/cnos/browser`.
|
|
32
|
-
5. Remove env-file dependencies app by app.
|
|
133
|
+
5. Remove handwritten env-file dependencies app by app.
|
|
@@ -5,18 +5,88 @@ description: Use CNOS workspaces to model multiple apps inside one repo.
|
|
|
5
5
|
|
|
6
6
|
# Workspaces and Monorepos
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
For monorepos, keep one authoritative `.cnos/` tree at the repo root and put a `.cnosrc.yml` anchor in each consuming app or package.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Repo root as both author and consumer:
|
|
11
11
|
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
cnos
|
|
15
|
-
|
|
12
|
+
```yaml
|
|
13
|
+
# .cnosrc.yml
|
|
14
|
+
root: ./.cnos
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Child app:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# apps/travel/.cnosrc.yml
|
|
21
|
+
root: ../../.cnos
|
|
22
|
+
workspace: travel
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`.cnosrc.yml` is the only discovery anchor. CNOS does not walk upward looking for `.cnos` directories. It looks for `.cnosrc.yml` within a bounded package-root search window, then resolves the real `.cnos` root from there.
|
|
26
|
+
|
|
27
|
+
Typical manifest shape:
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
workspaces:
|
|
31
|
+
default: root
|
|
32
|
+
items:
|
|
33
|
+
root: {}
|
|
34
|
+
travel:
|
|
35
|
+
extends: [root]
|
|
36
|
+
food:
|
|
37
|
+
extends: [root]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This lets you keep shared values in `root` and override only what each app needs in `travel`, `food`, or other child workspaces.
|
|
41
|
+
|
|
42
|
+
Read from an app package without passing a root manually:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import cnos from '@kitsy/cnos';
|
|
46
|
+
|
|
47
|
+
await cnos.ready();
|
|
48
|
+
console.log(cnos('value.app.name'));
|
|
16
49
|
```
|
|
17
50
|
|
|
18
51
|
Override per command when needed:
|
|
19
52
|
|
|
20
53
|
```bash
|
|
21
|
-
cnos list values --workspace
|
|
54
|
+
cnos list values --workspace travel
|
|
55
|
+
cnos build server --workspace travel --profile prod --to apps/travel/.cnos-server.json
|
|
22
56
|
```
|
|
57
|
+
|
|
58
|
+
## Runtime Projection
|
|
59
|
+
|
|
60
|
+
The authoring tree stays at repo root. Runtime consumers do not need the full `.cnos/` layout.
|
|
61
|
+
|
|
62
|
+
For server packaging:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cnos build server --workspace api-gateway --profile prod --to apps/api-gateway/.cnos-server.json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`@kitsy/cnos` then auto-loads in this order:
|
|
69
|
+
|
|
70
|
+
1. `__CNOS_PROJECTION__`
|
|
71
|
+
2. `.cnos-server.json`
|
|
72
|
+
3. full authoring resolution through `.cnosrc.yml`
|
|
73
|
+
|
|
74
|
+
Browser packages keep using public projection through Vite, Next, webpack, or `@kitsy/cnos/build`.
|
|
75
|
+
|
|
76
|
+
## Detach and Reattach
|
|
77
|
+
|
|
78
|
+
Detach a child package into a standalone CNOS root:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cnos workspace detach --package-root apps/travel
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This materializes the effective config into `apps/travel/.cnos`, rewrites `apps/travel/.cnosrc.yml` to point to that local root, and stops inheriting from the parent repo.
|
|
85
|
+
|
|
86
|
+
Reattach it later:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cnos workspace attach --package-root apps/travel
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This imports the standalone child config back into the parent workspace model, archives the detached `.cnos`, and restores the package anchor.
|
package/manifest.yml
CHANGED