@ontrails/config 1.0.0-beta.15 → 1.0.0-beta.16
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/CHANGELOG.md +34 -0
- package/README.md +1 -1
- package/package.json +10 -2
- package/src/define-config.ts +6 -3
- package/src/extensions.ts +1 -1
- package/src/index.ts +0 -1
- package/src/registry.ts +1 -1
- package/src/resolve.ts +4 -2
- package/.turbo/turbo-build.log +0 -1
- package/.turbo/turbo-lint.log +0 -3
- package/.turbo/turbo-typecheck.log +0 -1
- package/dist/app-config.d.ts +0 -65
- package/dist/app-config.d.ts.map +0 -1
- package/dist/app-config.js +0 -177
- package/dist/app-config.js.map +0 -1
- package/dist/collect.d.ts +0 -11
- package/dist/collect.d.ts.map +0 -1
- package/dist/collect.js +0 -81
- package/dist/collect.js.map +0 -1
- package/dist/compose.d.ts +0 -26
- package/dist/compose.d.ts.map +0 -1
- package/dist/compose.js +0 -19
- package/dist/compose.js.map +0 -1
- package/dist/config-layer.d.ts +0 -11
- package/dist/config-layer.d.ts.map +0 -1
- package/dist/config-layer.js +0 -6
- package/dist/config-layer.js.map +0 -1
- package/dist/config-resource.d.ts +0 -3
- package/dist/config-resource.d.ts.map +0 -1
- package/dist/config-resource.js +0 -26
- package/dist/config-resource.js.map +0 -1
- package/dist/define-config.d.ts +0 -61
- package/dist/define-config.d.ts.map +0 -1
- package/dist/define-config.js +0 -87
- package/dist/define-config.js.map +0 -1
- package/dist/derive/env.d.ts +0 -15
- package/dist/derive/env.d.ts.map +0 -1
- package/dist/derive/env.js +0 -65
- package/dist/derive/env.js.map +0 -1
- package/dist/derive/example.d.ts +0 -16
- package/dist/derive/example.d.ts.map +0 -1
- package/dist/derive/example.js +0 -138
- package/dist/derive/example.js.map +0 -1
- package/dist/derive/helpers.d.ts +0 -35
- package/dist/derive/helpers.d.ts.map +0 -1
- package/dist/derive/helpers.js +0 -116
- package/dist/derive/helpers.js.map +0 -1
- package/dist/derive/index.d.ts +0 -4
- package/dist/derive/index.d.ts.map +0 -1
- package/dist/derive/index.js +0 -4
- package/dist/derive/index.js.map +0 -1
- package/dist/derive/json-schema.d.ts +0 -18
- package/dist/derive/json-schema.d.ts.map +0 -1
- package/dist/derive/json-schema.js +0 -97
- package/dist/derive/json-schema.js.map +0 -1
- package/dist/derive-fields.d.ts +0 -25
- package/dist/derive-fields.d.ts.map +0 -1
- package/dist/derive-fields.js +0 -147
- package/dist/derive-fields.js.map +0 -1
- package/dist/derive-provenance.d.ts +0 -30
- package/dist/derive-provenance.d.ts.map +0 -1
- package/dist/derive-provenance.js +0 -101
- package/dist/derive-provenance.js.map +0 -1
- package/dist/doctor.d.ts +0 -27
- package/dist/doctor.d.ts.map +0 -1
- package/dist/doctor.js +0 -131
- package/dist/doctor.js.map +0 -1
- package/dist/extensions.d.ts +0 -38
- package/dist/extensions.d.ts.map +0 -1
- package/dist/extensions.js +0 -35
- package/dist/extensions.js.map +0 -1
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -20
- package/dist/index.js.map +0 -1
- package/dist/merge.d.ts +0 -16
- package/dist/merge.d.ts.map +0 -1
- package/dist/merge.js +0 -34
- package/dist/merge.js.map +0 -1
- package/dist/ref.d.ts +0 -29
- package/dist/ref.d.ts.map +0 -1
- package/dist/ref.js +0 -30
- package/dist/ref.js.map +0 -1
- package/dist/registry.d.ts +0 -24
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -12
- package/dist/registry.js.map +0 -1
- package/dist/resolve.d.ts +0 -21
- package/dist/resolve.d.ts.map +0 -1
- package/dist/resolve.js +0 -177
- package/dist/resolve.js.map +0 -1
- package/dist/secret-heuristics.d.ts +0 -10
- package/dist/secret-heuristics.d.ts.map +0 -1
- package/dist/secret-heuristics.js +0 -11
- package/dist/secret-heuristics.js.map +0 -1
- package/dist/trails/config-check.d.ts +0 -11
- package/dist/trails/config-check.d.ts.map +0 -1
- package/dist/trails/config-check.js +0 -53
- package/dist/trails/config-check.js.map +0 -1
- package/dist/trails/config-describe.d.ts +0 -12
- package/dist/trails/config-describe.d.ts.map +0 -1
- package/dist/trails/config-describe.js +0 -41
- package/dist/trails/config-describe.js.map +0 -1
- package/dist/trails/config-explain.d.ts +0 -8
- package/dist/trails/config-explain.d.ts.map +0 -1
- package/dist/trails/config-explain.js +0 -74
- package/dist/trails/config-explain.js.map +0 -1
- package/dist/trails/config-init.d.ts +0 -9
- package/dist/trails/config-init.d.ts.map +0 -1
- package/dist/trails/config-init.js +0 -78
- package/dist/trails/config-init.js.map +0 -1
- package/dist/workspace.d.ts +0 -9
- package/dist/workspace.d.ts.map +0 -1
- package/dist/workspace.js +0 -49
- package/dist/workspace.js.map +0 -1
- package/dist/zod-utils.d.ts +0 -14
- package/dist/zod-utils.d.ts.map +0 -1
- package/dist/zod-utils.js +0 -41
- package/dist/zod-utils.js.map +0 -1
- package/src/__tests__/app-config.test.ts +0 -342
- package/src/__tests__/compose.test.ts +0 -59
- package/src/__tests__/config-check.test.ts +0 -171
- package/src/__tests__/config-describe.test.ts +0 -154
- package/src/__tests__/config-explain.test.ts +0 -167
- package/src/__tests__/config-init.test.ts +0 -210
- package/src/__tests__/config-resource.test.ts +0 -87
- package/src/__tests__/define-config.test.ts +0 -269
- package/src/__tests__/derive-fields.test.ts +0 -158
- package/src/__tests__/derive-provenance.test.ts +0 -139
- package/src/__tests__/derive.test.ts +0 -269
- package/src/__tests__/doctor.test.ts +0 -172
- package/src/__tests__/extensions.test.ts +0 -134
- package/src/__tests__/ref.test.ts +0 -35
- package/src/__tests__/resolve.test.ts +0 -246
- package/src/__tests__/workspace.test.ts +0 -64
- package/src/workspace.ts +0 -56
- package/tsconfig.json +0 -9
- package/tsconfig.tests.json +0 -10
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
|
|
4
|
-
import { env } from '../extensions.js';
|
|
5
|
-
import { deriveConfig } from '../resolve.js';
|
|
6
|
-
|
|
7
|
-
const baseSchema = z.object({
|
|
8
|
-
debug: z.boolean().default(false),
|
|
9
|
-
host: z.string().default('localhost'),
|
|
10
|
-
port: z.number().default(3000),
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe('deriveConfig', () => {
|
|
14
|
-
describe('schema defaults', () => {
|
|
15
|
-
test('applies schema defaults when no other source provides values', () => {
|
|
16
|
-
const result = deriveConfig({ schema: baseSchema });
|
|
17
|
-
|
|
18
|
-
expect(result.isOk()).toBe(true);
|
|
19
|
-
expect(result.unwrap()).toEqual({
|
|
20
|
-
debug: false,
|
|
21
|
-
host: 'localhost',
|
|
22
|
-
port: 3000,
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe('base config', () => {
|
|
28
|
-
test('overrides schema defaults', () => {
|
|
29
|
-
const result = deriveConfig({
|
|
30
|
-
base: { host: 'example.com', port: 8080 },
|
|
31
|
-
schema: baseSchema,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
expect(result.isOk()).toBe(true);
|
|
35
|
-
const value = result.unwrap();
|
|
36
|
-
expect(value.host).toBe('example.com');
|
|
37
|
-
expect(value.port).toBe(8080);
|
|
38
|
-
// Schema default preserved for unspecified fields
|
|
39
|
-
expect(value.debug).toBe(false);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
describe('profiles', () => {
|
|
44
|
-
test('overrides base config for matching profile', () => {
|
|
45
|
-
const result = deriveConfig({
|
|
46
|
-
base: { host: 'example.com', port: 8080 },
|
|
47
|
-
profile: 'production',
|
|
48
|
-
profiles: {
|
|
49
|
-
production: { host: 'prod.example.com', port: 443 },
|
|
50
|
-
},
|
|
51
|
-
schema: baseSchema,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
expect(result.isOk()).toBe(true);
|
|
55
|
-
const value = result.unwrap();
|
|
56
|
-
expect(value.host).toBe('prod.example.com');
|
|
57
|
-
expect(value.port).toBe(443);
|
|
58
|
-
expect(value.debug).toBe(false);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('silently ignores unrecognized profile (base only)', () => {
|
|
62
|
-
const result = deriveConfig({
|
|
63
|
-
base: { host: 'example.com' },
|
|
64
|
-
profile: 'staging',
|
|
65
|
-
profiles: {
|
|
66
|
-
production: { host: 'prod.example.com' },
|
|
67
|
-
},
|
|
68
|
-
schema: baseSchema,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
expect(result.isOk()).toBe(true);
|
|
72
|
-
expect(result.unwrap().host).toBe('example.com');
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe('local overrides', () => {
|
|
77
|
-
test('deep-merge on top of profile', () => {
|
|
78
|
-
const nestedSchema = z.object({
|
|
79
|
-
db: z
|
|
80
|
-
.object({
|
|
81
|
-
host: z.string().default('localhost'),
|
|
82
|
-
port: z.number().default(5432),
|
|
83
|
-
})
|
|
84
|
-
.default({}),
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const result = deriveConfig({
|
|
88
|
-
base: { db: { host: 'db.example.com', port: 5432 } },
|
|
89
|
-
localOverrides: { db: { port: 9999 } },
|
|
90
|
-
profile: 'production',
|
|
91
|
-
profiles: {
|
|
92
|
-
production: { db: { host: 'prod-db.example.com' } },
|
|
93
|
-
},
|
|
94
|
-
schema: nestedSchema,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
expect(result.isOk()).toBe(true);
|
|
98
|
-
const value = result.unwrap();
|
|
99
|
-
expect(value.db.host).toBe('prod-db.example.com');
|
|
100
|
-
expect(value.db.port).toBe(9999);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe('env var overrides', () => {
|
|
105
|
-
test('overrides all other sources', () => {
|
|
106
|
-
const schema = z.object({
|
|
107
|
-
host: env(z.string(), 'APP_HOST').default('localhost'),
|
|
108
|
-
port: env(z.number(), 'APP_PORT').default(3000),
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
const result = deriveConfig({
|
|
112
|
-
base: { host: 'example.com', port: 8080 },
|
|
113
|
-
env: { APP_HOST: 'env-host.example.com', APP_PORT: '9090' },
|
|
114
|
-
schema,
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
expect(result.isOk()).toBe(true);
|
|
118
|
-
const value = result.unwrap();
|
|
119
|
-
expect(value.host).toBe('env-host.example.com');
|
|
120
|
-
expect(value.port).toBe(9090);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('coerces string to number', () => {
|
|
124
|
-
const schema = z.object({
|
|
125
|
-
port: env(z.number(), 'PORT').default(3000),
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const result = deriveConfig({
|
|
129
|
-
env: { PORT: '8080' },
|
|
130
|
-
schema,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
expect(result.isOk()).toBe(true);
|
|
134
|
-
expect(result.unwrap().port).toBe(8080);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
test('rejects non-numeric string with Zod error instead of NaN', () => {
|
|
138
|
-
const schema = z.object({
|
|
139
|
-
port: env(z.number(), 'PORT').default(3000),
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
const result = deriveConfig({
|
|
143
|
-
env: { PORT: 'abc' },
|
|
144
|
-
schema,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
expect(result.isErr()).toBe(true);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test('coerces string to boolean', () => {
|
|
151
|
-
const schema = z.object({
|
|
152
|
-
debug: env(z.boolean(), 'DEBUG').default(false),
|
|
153
|
-
verbose: env(z.boolean(), 'VERBOSE').default(false),
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
const trueValues = deriveConfig({
|
|
157
|
-
env: { DEBUG: 'true', VERBOSE: '1' },
|
|
158
|
-
schema,
|
|
159
|
-
});
|
|
160
|
-
expect(trueValues.isOk()).toBe(true);
|
|
161
|
-
expect(trueValues.unwrap().debug).toBe(true);
|
|
162
|
-
expect(trueValues.unwrap().verbose).toBe(true);
|
|
163
|
-
|
|
164
|
-
const falseValues = deriveConfig({
|
|
165
|
-
env: { DEBUG: 'false', VERBOSE: '0' },
|
|
166
|
-
schema,
|
|
167
|
-
});
|
|
168
|
-
expect(falseValues.isOk()).toBe(true);
|
|
169
|
-
expect(falseValues.unwrap().debug).toBe(false);
|
|
170
|
-
expect(falseValues.unwrap().verbose).toBe(false);
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
describe('validation', () => {
|
|
175
|
-
test('missing required field returns Result.err', () => {
|
|
176
|
-
const schema = z.object({
|
|
177
|
-
required: z.string(),
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const result = deriveConfig({ schema });
|
|
181
|
-
|
|
182
|
-
expect(result.isErr()).toBe(true);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
describe('mutation safety', () => {
|
|
187
|
-
test('repeated resolve() calls do not mutate the original base', () => {
|
|
188
|
-
const schema = z.object({
|
|
189
|
-
host: env(z.string(), 'APP_HOST').default('localhost'),
|
|
190
|
-
});
|
|
191
|
-
const base = { host: 'dev-host' };
|
|
192
|
-
|
|
193
|
-
const first = deriveConfig({
|
|
194
|
-
base,
|
|
195
|
-
env: { APP_HOST: 'env-host' },
|
|
196
|
-
schema,
|
|
197
|
-
});
|
|
198
|
-
expect(first.isOk()).toBe(true);
|
|
199
|
-
expect(first.unwrap().host).toBe('env-host');
|
|
200
|
-
|
|
201
|
-
const second = deriveConfig({ base, schema });
|
|
202
|
-
expect(second.isOk()).toBe(true);
|
|
203
|
-
expect(second.unwrap().host).toBe('dev-host');
|
|
204
|
-
expect(base.host).toBe('dev-host');
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
describe('full stack', () => {
|
|
209
|
-
test('all 5 sources compose correctly', () => {
|
|
210
|
-
const schema = z.object({
|
|
211
|
-
apiUrl: env(z.string(), 'API_URL').default('http://localhost'),
|
|
212
|
-
debug: env(z.boolean(), 'DEBUG').default(false),
|
|
213
|
-
local: z.string().default('default-local'),
|
|
214
|
-
name: z.string().default('app'),
|
|
215
|
-
port: z.number().default(3000),
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
const result = deriveConfig({
|
|
219
|
-
// base overrides name
|
|
220
|
-
base: { name: 'my-app', port: 8080 },
|
|
221
|
-
// env overrides debug and apiUrl
|
|
222
|
-
env: { API_URL: 'https://api.prod.com', DEBUG: 'true' },
|
|
223
|
-
// local overrides local
|
|
224
|
-
localOverrides: { local: 'my-local-value' },
|
|
225
|
-
// profile overrides port
|
|
226
|
-
profile: 'production',
|
|
227
|
-
profiles: { production: { port: 443 } },
|
|
228
|
-
schema,
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
expect(result.isOk()).toBe(true);
|
|
232
|
-
const value = result.unwrap();
|
|
233
|
-
// Schema default
|
|
234
|
-
// (nothing left at just default — name was overridden by base)
|
|
235
|
-
// Base
|
|
236
|
-
expect(value.name).toBe('my-app');
|
|
237
|
-
// Profile overrides base port
|
|
238
|
-
expect(value.port).toBe(443);
|
|
239
|
-
// Local overrides
|
|
240
|
-
expect(value.local).toBe('my-local-value');
|
|
241
|
-
// Env overrides
|
|
242
|
-
expect(value.apiUrl).toBe('https://api.prod.com');
|
|
243
|
-
expect(value.debug).toBe(true);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
|
|
2
|
-
import { mkdtemp, readdir, readFile, rm } from 'node:fs/promises';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
|
|
6
|
-
import { ensureWorkspace } from '../workspace.js';
|
|
7
|
-
|
|
8
|
-
describe('ensureWorkspace', () => {
|
|
9
|
-
let root: string;
|
|
10
|
-
|
|
11
|
-
beforeEach(async () => {
|
|
12
|
-
root = await mkdtemp(join(tmpdir(), 'trails-ws-'));
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterEach(async () => {
|
|
16
|
-
await rm(root, { force: true, recursive: true });
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe('directory creation', () => {
|
|
20
|
-
test('creates .trails/ directory', async () => {
|
|
21
|
-
await ensureWorkspace(root);
|
|
22
|
-
const entries = await readdir(join(root, '.trails'));
|
|
23
|
-
expect(entries).toContain('config');
|
|
24
|
-
expect(entries).toContain('dev');
|
|
25
|
-
expect(entries).toContain('generated');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test('creates all expected subdirectories', async () => {
|
|
29
|
-
await ensureWorkspace(root);
|
|
30
|
-
const config = await readdir(join(root, '.trails', 'config'));
|
|
31
|
-
expect(config).toBeDefined();
|
|
32
|
-
const dev = await readdir(join(root, '.trails', 'dev'));
|
|
33
|
-
expect(dev).toBeDefined();
|
|
34
|
-
const generated = await readdir(join(root, '.trails', 'generated'));
|
|
35
|
-
expect(generated).toBeDefined();
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe('.gitignore', () => {
|
|
40
|
-
test('writes .gitignore on first run', async () => {
|
|
41
|
-
await ensureWorkspace(root);
|
|
42
|
-
const content = await readFile(
|
|
43
|
-
join(root, '.trails', '.gitignore'),
|
|
44
|
-
'utf8'
|
|
45
|
-
);
|
|
46
|
-
expect(content).toContain('config/');
|
|
47
|
-
expect(content).toContain('dev/');
|
|
48
|
-
expect(content).toContain('generated/');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('does not overwrite existing .gitignore', async () => {
|
|
52
|
-
await ensureWorkspace(root);
|
|
53
|
-
const customContent = '# custom\n*\n';
|
|
54
|
-
await Bun.write(join(root, '.trails', '.gitignore'), customContent);
|
|
55
|
-
|
|
56
|
-
await ensureWorkspace(root);
|
|
57
|
-
const content = await readFile(
|
|
58
|
-
join(root, '.trails', '.gitignore'),
|
|
59
|
-
'utf8'
|
|
60
|
-
);
|
|
61
|
-
expect(content).toBe(customContent);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
package/src/workspace.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ensure the `.trails/` workspace directory exists with proper structure.
|
|
3
|
-
*
|
|
4
|
-
* Auto-creates on first framework operation. The workspace holds local
|
|
5
|
-
* config overrides, development state, and generated artifacts that
|
|
6
|
-
* should not be committed to source control.
|
|
7
|
-
*/
|
|
8
|
-
import { mkdir } from 'node:fs/promises';
|
|
9
|
-
import { join } from 'node:path';
|
|
10
|
-
|
|
11
|
-
const WORKSPACE_DIRS = ['config', 'dev', 'generated'] as const;
|
|
12
|
-
|
|
13
|
-
const GITIGNORE_CONTENT = [
|
|
14
|
-
'# Local config overrides',
|
|
15
|
-
'config/',
|
|
16
|
-
'',
|
|
17
|
-
'# Development state',
|
|
18
|
-
'dev/',
|
|
19
|
-
'',
|
|
20
|
-
'# Generated artifacts',
|
|
21
|
-
'generated/',
|
|
22
|
-
'',
|
|
23
|
-
'# Shared Trails database',
|
|
24
|
-
'trails.db',
|
|
25
|
-
'trails.db-shm',
|
|
26
|
-
'trails.db-wal',
|
|
27
|
-
'',
|
|
28
|
-
].join('\n');
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Write `.gitignore` inside the workspace directory if it does not already exist.
|
|
32
|
-
*/
|
|
33
|
-
const writeGitignoreIfMissing = async (trailsDir: string): Promise<void> => {
|
|
34
|
-
const gitignorePath = join(trailsDir, '.gitignore');
|
|
35
|
-
const file = Bun.file(gitignorePath);
|
|
36
|
-
if (!(await file.exists())) {
|
|
37
|
-
await Bun.write(gitignorePath, GITIGNORE_CONTENT);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Ensure the `.trails/` workspace directory exists with proper structure.
|
|
43
|
-
*
|
|
44
|
-
* Creates `config/`, `dev/`, and `generated/` subdirectories plus a
|
|
45
|
-
* `.gitignore` that excludes local-only files. Safe to call repeatedly —
|
|
46
|
-
* existing files are never overwritten.
|
|
47
|
-
*/
|
|
48
|
-
export const ensureWorkspace = async (root: string): Promise<void> => {
|
|
49
|
-
const trailsDir = join(root, '.trails');
|
|
50
|
-
|
|
51
|
-
await Promise.all(
|
|
52
|
-
WORKSPACE_DIRS.map((d) => mkdir(join(trailsDir, d), { recursive: true }))
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
await writeGitignoreIfMissing(trailsDir);
|
|
56
|
-
};
|
package/tsconfig.json
DELETED
package/tsconfig.tests.json
DELETED
package/tsconfig.tsbuildinfo
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["./src/app-config.ts","./src/collect.ts","./src/compose.ts","./src/config-resource.ts","./src/define-config.ts","./src/derive-fields.ts","./src/derive-provenance.ts","./src/doctor.ts","./src/extensions.ts","./src/index.ts","./src/merge.ts","./src/ref.ts","./src/registry.ts","./src/resolve.ts","./src/secret-heuristics.ts","./src/workspace.ts","./src/zod-utils.ts","./src/derive/env.ts","./src/derive/example.ts","./src/derive/helpers.ts","./src/derive/index.ts","./src/derive/json-schema.ts","./src/trails/config-check.ts","./src/trails/config-describe.ts","./src/trails/config-explain.ts","./src/trails/config-init.ts"],"version":"5.9.3"}
|