@arki/env 0.0.1 → 0.0.2

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.
@@ -2,7 +2,7 @@ export declare const contracts: {
2
2
  json: <T extends import("zod").ZodType>(schema: T) => import("zod").ZodPipe<import("zod").ZodString, import("zod").ZodTransform<Awaited<import("zod").infer<T>>, string>>;
3
3
  csvArray: <T extends import("zod").ZodType>(itemSchema: T) => import("zod").ZodPipe<import("zod").ZodTransform<unknown, unknown>, import("zod").ZodArray<T>>;
4
4
  csvSet: <T extends import("zod").ZodType>(itemSchema: T) => import("zod").ZodPipe<import("zod").ZodTransform<unknown, unknown>, import("zod").ZodArray<T>>;
5
- url: (defaultValue?: string) => import("zod").ZodString | import("zod").ZodDefault<import("zod").ZodString>;
5
+ url: (defaultValue?: string) => import("zod").ZodURL | import("zod").ZodDefault<import("zod").ZodURL>;
6
6
  databaseUrl: () => import("zod").ZodURL;
7
7
  redisUrl: () => import("zod").ZodURL;
8
8
  string: (defaultValue?: string) => import("zod").ZodString | import("zod").ZodDefault<import("zod").ZodString>;
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  export declare const urlContracts: {
3
- url: (defaultValue?: string) => z.ZodString | z.ZodDefault<z.ZodString>;
3
+ url: (defaultValue?: string) => z.ZodURL | z.ZodDefault<z.ZodURL>;
4
4
  databaseUrl: () => z.ZodURL;
5
5
  redisUrl: () => z.ZodURL;
6
6
  };
@@ -1 +1 @@
1
- {"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../src/contracts/urls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,YAAY;yBACF,MAAM;;;CAiB5B,CAAC"}
1
+ {"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../src/contracts/urls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,YAAY;yBACF,MAAM;;;CAoB5B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  export const urlContracts = {
3
3
  url: (defaultValue) => {
4
- const schema = z.string().url();
4
+ const schema = z.url();
5
5
  return defaultValue ? schema.default(defaultValue) : schema;
6
6
  },
7
7
  databaseUrl: () => z
@@ -1 +1 @@
1
- {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../src/contracts/urls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,EAAE,CAAC,YAAqB,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9D,CAAC;IAED,WAAW,EAAE,GAAG,EAAE,CAChB,CAAC;SACE,GAAG,EAAE;SACL,MAAM,CACL,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EACvE,2DAA2D,CAC5D;IAEL,QAAQ,EAAE,GAAG,EAAE,CACb,CAAC;SACE,GAAG,EAAE;SACL,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,iDAAiD,CAAC;CACjI,CAAC"}
1
+ {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../src/contracts/urls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,GAAG,EAAE,CAAC,YAAqB,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9D,CAAC;IAED,WAAW,EAAE,GAAG,EAAE,CAChB,CAAC;SACE,GAAG,EAAE;SACL,MAAM,CACL,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EACvE,2DAA2D,CAC5D;IAEL,QAAQ,EAAE,GAAG,EAAE,CACb,CAAC;SACE,GAAG,EAAE;SACL,MAAM,CACL,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EAChE,iDAAiD,CAClD;CACN,CAAC"}
@@ -1,13 +1,54 @@
1
+ import { createEnv } from '@t3-oss/env-core';
2
+ import type { CreateEnv, DefaultCombinedSchema } from '@t3-oss/env-core';
1
3
  import type { ZodType } from 'zod';
2
- type CoreEnvConfig = {
3
- server: Record<string, ZodType>;
4
+ /** The issue shape t3-oss hands to `onValidationError`, derived so it stays in sync with the lib. */
5
+ type ValidationIssues = Parameters<NonNullable<Parameters<typeof createEnv>[0]['onValidationError']>>[0];
6
+ /**
7
+ * Thin, type-preserving wrapper over `@t3-oss/env-core`'s `createEnv`. Generic over the server,
8
+ * client, shared and composed schemas so the parsed env keeps its exact inferred types — the wrapper
9
+ * adds the ARKI defaults (auto `runtimeEnv`, prod-safe `skipValidation`, a legible labelled error
10
+ * handler) without widening any value to `unknown`.
11
+ *
12
+ * `TPrefix` is kept as a string-literal generic on purpose: `createEnv` uses it to enforce that
13
+ * client keys (and only client keys) carry the prefix. Widening it to `string` would make every
14
+ * server key collapse to a type-level `ErrorMessage`, so the prefix must stay a literal.
15
+ */
16
+ export declare function defineEnv<TServer extends Record<string, ZodType>, TClient extends Record<string, ZodType> = NonNullable<unknown>, TShared extends Record<string, ZodType> = NonNullable<unknown>, const TPrefix extends string = '', const TExtends extends Array<Record<string, unknown>> = []>(config: {
17
+ /**
18
+ * Label shown in validation-error logs, e.g. `'@acme/backend'`. Without it a misconfigured
19
+ * deploy logs a bare "Invalid environment variables" with no hint which env failed — exactly the
20
+ * blind failure this wrapper exists to prevent.
21
+ */
22
+ name?: string;
23
+ server: TServer;
24
+ /** Client-side schema. Every key must start with `clientPrefix` (enforced by `createEnv`). */
25
+ client?: TClient;
26
+ /** Prefix client keys must carry, e.g. `'VITE_'`. Defaults to `''` (no client vars). */
27
+ clientPrefix?: TPrefix;
28
+ /** Shared vars available to both client and server, unprefixed (e.g. `NODE_ENV`). */
29
+ shared?: TShared;
30
+ /**
31
+ * Already-built envs to compose in (e.g. `@arki/auth`, `@arki/db`). Their parsed variables merge
32
+ * into the result with full types; each was validated by its own `createEnv` at import time.
33
+ */
34
+ extends?: TExtends;
35
+ /**
36
+ * Explicit runtime source. Omit it and `defineEnv` auto-builds one by reading `process.env` for
37
+ * every declared key — correct for any server-side env. Provide it only when the auto-build would
38
+ * be wrong: Vite/`start` apps whose client vars come from `import.meta.env` in the browser, or
39
+ * keys with a fallback/alias (e.g. `DB_URL: process.env.DB_URL ?? process.env.DATABASE_URL`).
40
+ */
41
+ runtimeEnv?: Record<string, string | boolean | number | undefined>;
4
42
  options?: {
5
43
  skipValidation?: boolean;
6
- onValidationError?: (issues: any) => never;
44
+ /**
45
+ * Treat empty-string env values as `undefined` so defaults apply (e.g. `PORT=` in `.env`, or a
46
+ * Docker arg baked as `X=""`). Defaults to `true` — set `false` only if an app intentionally
47
+ * accepts `""` as a valid required string.
48
+ */
49
+ emptyStringAsUndefined?: boolean;
50
+ onValidationError?: (issues: ValidationIssues) => never;
7
51
  };
8
- };
9
- export declare function defineEnv(config: CoreEnvConfig): Readonly<{
10
- [x: string]: unknown;
11
- }>;
52
+ }): CreateEnv<DefaultCombinedSchema<TServer, TClient, TShared>, TExtends>;
12
53
  export {};
13
54
  //# sourceMappingURL=define-env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"define-env.d.ts","sourceRoot":"","sources":["../../src/core/define-env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,KAAK,aAAa,GAAG;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,OAAO,CAAC;QAEzB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,KAAK,CAAC;KAC5C,CAAC;CACH,CAAC;AAEF,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa;;GAiB9C"}
1
+ {"version":3,"file":"define-env.d.ts","sourceRoot":"","sources":["../../src/core/define-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,qGAAqG;AACrG,KAAK,gBAAgB,GAAG,UAAU,CAChC,WAAW,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAClE,CAAC,CAAC,CAAC,CAAC;AAkBL;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,EAC9D,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,EAC9D,KAAK,CAAC,OAAO,SAAS,MAAM,GAAG,EAAE,EACjC,KAAK,CAAC,QAAQ,SAAS,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,EAC1D,MAAM,EAAE;IACR;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wFAAwF;IACxF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qFAAqF;IACrF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;IACnE,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB;;;;WAIG;QACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,KAAK,CAAC;KACzD,CAAC;CACH,GAAG,SAAS,CAAC,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAwDxE"}
@@ -1,18 +1,76 @@
1
1
  import { createEnv } from '@t3-oss/env-core';
2
+ /**
3
+ * Fold validation issues into a human-legible, log-pipeline-safe string. The t3-oss default handler
4
+ * logs `issues` as a raw object, which platforms like Coolify collapse to `[Object]` — so the var
5
+ * that actually failed never reaches the logs. A flat ` path: message` list survives transport.
6
+ */
7
+ function formatIssues(name, issues) {
8
+ const label = name ? `[${name}] ` : '';
9
+ const lines = issues.map(issue => {
10
+ const path = (issue.path ?? [])
11
+ .map(seg => (typeof seg === 'object' && seg !== null && 'key' in seg ? String(seg.key) : String(seg)))
12
+ .join('.');
13
+ return ` ${path || '(root)'}: ${issue.message}`;
14
+ });
15
+ return `❌ ${label}Invalid environment variables:\n${lines.join('\n')}`;
16
+ }
17
+ /**
18
+ * Thin, type-preserving wrapper over `@t3-oss/env-core`'s `createEnv`. Generic over the server,
19
+ * client, shared and composed schemas so the parsed env keeps its exact inferred types — the wrapper
20
+ * adds the ARKI defaults (auto `runtimeEnv`, prod-safe `skipValidation`, a legible labelled error
21
+ * handler) without widening any value to `unknown`.
22
+ *
23
+ * `TPrefix` is kept as a string-literal generic on purpose: `createEnv` uses it to enforce that
24
+ * client keys (and only client keys) carry the prefix. Widening it to `string` would make every
25
+ * server key collapse to a type-level `ErrorMessage`, so the prefix must stay a literal.
26
+ */
2
27
  export function defineEnv(config) {
3
28
  const skipValidation = config.options?.skipValidation ?? (!!process.env.CI || process.env.NODE_ENV !== 'development');
4
- // Auto-generate runtimeEnv (no Next.js bundler constraints)
5
- const runtimeEnv = {};
6
- for (const key of Object.keys(config.server)) {
7
- runtimeEnv[key] = process.env[key];
29
+ // Use the caller's explicit runtimeEnv when supplied (Vite client vars via import.meta.env, or
30
+ // fallback aliases). Otherwise auto-build from every declared key (server + client + shared);
31
+ // createEnv tolerates keys absent from process.env (they parse as undefined → optional/default).
32
+ let runtimeEnv;
33
+ if (config.runtimeEnv) {
34
+ runtimeEnv = config.runtimeEnv;
8
35
  }
9
- return createEnv({
36
+ else {
37
+ runtimeEnv = {};
38
+ for (const key of Object.keys(config.server)) {
39
+ runtimeEnv[key] = process.env[key];
40
+ }
41
+ for (const key of Object.keys(config.client ?? {})) {
42
+ runtimeEnv[key] = process.env[key];
43
+ }
44
+ for (const key of Object.keys(config.shared ?? {})) {
45
+ runtimeEnv[key] = process.env[key];
46
+ }
47
+ }
48
+ const onValidationError = config.options?.onValidationError ??
49
+ ((issues) => {
50
+ const message = formatIssues(config.name, issues);
51
+ console.error(message);
52
+ throw new Error(message);
53
+ });
54
+ // `createEnv`'s `server`/`client` params are conditional on `clientPrefix` being a *concrete*
55
+ // string literal; inside a generic wrapper `TPrefix` is abstract, so the body cannot be verified
56
+ // for all prefixes and the call argument must be asserted once. The PUBLIC contract stays exact:
57
+ // the explicit return type above reconstructs `createEnv`'s own result from the generics, and the
58
+ // caller's `server`/`client`/`extends` are fully type-checked against `TServer`/`TClient`/`TExtends`
59
+ // at the call site. This is the only seam where types are asserted — value types are never widened.
60
+ const options = {
61
+ shared: config.shared ?? {},
62
+ extends: config.extends,
10
63
  server: config.server,
11
- client: {},
12
- clientPrefix: '',
64
+ client: config.client ?? {},
65
+ clientPrefix: config.clientPrefix ?? '',
13
66
  runtimeEnv,
14
67
  skipValidation,
15
- onValidationError: config.options?.onValidationError,
16
- });
68
+ // Default ON: in containerized deploys an unset var is baked as "" (e.g. Docker `ENV X=${X}`
69
+ // with no build arg), not left absent. Treating "" as undefined lets `.default()`/`.optional()`
70
+ // apply as intended instead of failing format checks like `z.url()` on an empty string.
71
+ emptyStringAsUndefined: config.options?.emptyStringAsUndefined ?? true,
72
+ onValidationError,
73
+ };
74
+ return createEnv(options);
17
75
  }
18
76
  //# sourceMappingURL=define-env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"define-env.js","sourceRoot":"","sources":["../../src/core/define-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAY7C,MAAM,UAAU,SAAS,CAAC,MAAqB;IAC7C,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,EAAE,cAAc,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC;IAEtH,4DAA4D;IAC5D,MAAM,UAAU,GAAuC,EAAE,CAAC;IAC1D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7C,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,SAAS,CAAC;QACf,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,EAAE;QACV,YAAY,EAAE,EAAE;QAChB,UAAU;QACV,cAAc;QACd,iBAAiB,EAAE,MAAM,CAAC,OAAO,EAAE,iBAAiB;KACrD,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"define-env.js","sourceRoot":"","sources":["../../src/core/define-env.ts"],"names":[],"mappings":"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"}
package/dist/dot.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * DOT adapter for `@arki/env`.
3
3
  *
4
- * Wraps `defineEnv()` as a `DotPip` so a DOT app can validate its
4
+ * Wraps `defineEnv()` as a DOT pip so a DOT app can validate its
5
5
  * environment alongside any other services. The pip is sync (env
6
6
  * validation is sync), so the `boot` hook returns the validated env
7
- * object synchronously through the standard `services` channel.
7
+ * object synchronously through the standard provides channel.
8
8
  *
9
9
  * @example
10
10
  * ```ts
@@ -19,11 +19,21 @@
19
19
  * console.log(app.services.env.PORT); // number, typed.
20
20
  * ```
21
21
  *
22
+ * To mount a second env scope in the same app, rename the published wire
23
+ * key at the mount site:
24
+ *
25
+ * ```ts
26
+ * import { rename } from '@arki/dot';
27
+ *
28
+ * .use(env({ schema: appSchema }))
29
+ * .use(rename(env({ schema: publicSchema }), { env: 'publicEnv' }, 'public-env'))
30
+ * ```
31
+ *
22
32
  * The `@arki/dot` package is an OPTIONAL peer of `@arki/env`. Importing
23
33
  * this adapter without `@arki/dot` installed will fail at module load —
24
34
  * that is intentional: the adapter only makes sense in a DOT app.
25
35
  */
26
- import { type DotPip } from '@arki/dot/pip';
36
+ import { type EmptyShape, type Pip } from '@arki/dot/pip';
27
37
  import type { ZodType } from 'zod';
28
38
  /**
29
39
  * Options for the env DOT adapter.
@@ -34,11 +44,6 @@ import type { ZodType } from 'zod';
34
44
  export type EnvDotOptions<TSchema extends Record<string, ZodType>> = {
35
45
  /** Zod schemas for each env var the pip validates. */
36
46
  readonly schema: TSchema;
37
- /**
38
- * Pip name override. Defaults to `'env'`. Use this only when
39
- * composing multiple env scopes inside the same app (rare).
40
- */
41
- readonly name?: string;
42
47
  /**
43
48
  * Forwarded to `defineEnv`. If `true`, the validator is skipped
44
49
  * entirely. By default, validation is skipped when `CI` is set or
@@ -46,14 +51,7 @@ export type EnvDotOptions<TSchema extends Record<string, ZodType>> = {
46
51
  */
47
52
  readonly skipValidation?: boolean;
48
53
  };
49
- /**
50
- * The shape of services published by the env adapter.
51
- *
52
- * The key is configurable via `options.name` (defaults to `'env'`) so
53
- * downstream pips can pick the right env when multiple env scopes
54
- * exist. For the default single-env case, `app.services.env` is the
55
- * validated record.
56
- */
54
+ /** The shape of services published by the env adapter. */
57
55
  export type EnvServices<TSchema extends Record<string, ZodType>> = {
58
56
  readonly env: {
59
57
  readonly [K in keyof TSchema]: TSchema[K] extends ZodType<infer U> ? U : never;
@@ -63,7 +61,7 @@ export type EnvServices<TSchema extends Record<string, ZodType>> = {
63
61
  * Build a DOT pip that validates and publishes a typed `env` service.
64
62
  *
65
63
  * @param options - Schema + optional config.
66
- * @returns A `DotPip` that registers an `env`-kind service.
64
+ * @returns A pip that publishes `services.env`.
67
65
  */
68
- export declare function env<TSchema extends Record<string, ZodType>>(options: EnvDotOptions<TSchema>): DotPip<EnvServices<TSchema>>;
66
+ export declare function env<TSchema extends Record<string, ZodType>>(options: EnvDotOptions<TSchema>): Pip<EmptyShape, EnvServices<TSchema>>;
69
67
  //# sourceMappingURL=dot.d.ts.map
package/dist/dot.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dot.d.ts","sourceRoot":"","sources":["../src/dot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAInC;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACnE,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACjE,QAAQ,CAAC,GAAG,EAAE;QAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;KAAE,CAAC;CAClG,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAC9B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAyB9B"}
1
+ {"version":3,"file":"dot.d.ts","sourceRoot":"","sources":["../src/dot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAO,KAAK,UAAU,EAAE,KAAK,GAAG,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAInC;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACnE,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACjE,QAAQ,CAAC,GAAG,EAAE;QAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;KAAE,CAAC;CAClG,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAC9B,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAuBvC"}
package/dist/dot.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * DOT adapter for `@arki/env`.
3
3
  *
4
- * Wraps `defineEnv()` as a `DotPip` so a DOT app can validate its
4
+ * Wraps `defineEnv()` as a DOT pip so a DOT app can validate its
5
5
  * environment alongside any other services. The pip is sync (env
6
6
  * validation is sync), so the `boot` hook returns the validated env
7
- * object synchronously through the standard `services` channel.
7
+ * object synchronously through the standard provides channel.
8
8
  *
9
9
  * @example
10
10
  * ```ts
@@ -19,24 +19,32 @@
19
19
  * console.log(app.services.env.PORT); // number, typed.
20
20
  * ```
21
21
  *
22
+ * To mount a second env scope in the same app, rename the published wire
23
+ * key at the mount site:
24
+ *
25
+ * ```ts
26
+ * import { rename } from '@arki/dot';
27
+ *
28
+ * .use(env({ schema: appSchema }))
29
+ * .use(rename(env({ schema: publicSchema }), { env: 'publicEnv' }, 'public-env'))
30
+ * ```
31
+ *
22
32
  * The `@arki/dot` package is an OPTIONAL peer of `@arki/env`. Importing
23
33
  * this adapter without `@arki/dot` installed will fail at module load —
24
34
  * that is intentional: the adapter only makes sense in a DOT app.
25
35
  */
26
- import { defineDotPip } from '@arki/dot/pip';
36
+ import { pip } from '@arki/dot/pip';
27
37
  import { defineEnv } from './core/define-env.js';
28
38
  /**
29
39
  * Build a DOT pip that validates and publishes a typed `env` service.
30
40
  *
31
41
  * @param options - Schema + optional config.
32
- * @returns A `DotPip` that registers an `env`-kind service.
42
+ * @returns A pip that publishes `services.env`.
33
43
  */
34
44
  export function env(options) {
35
- const name = options.name ?? 'env';
36
- return defineDotPip({
37
- name,
45
+ return pip({
46
+ name: 'env',
38
47
  version: '0.1.0',
39
- provides: ['env'],
40
48
  configure(ctx) {
41
49
  ctx.registerService('env', 'env');
42
50
  },
@@ -52,7 +60,7 @@ export function env(options) {
52
60
  // The runtime guarantee comes from Zod-side validation inside
53
61
  // `defineEnv`. No `any` involved — the cast is type-only.
54
62
  const envObject = validated;
55
- return { services: { env: envObject } };
63
+ return { env: envObject };
56
64
  },
57
65
  });
58
66
  }
package/dist/dot.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dot.js","sourceRoot":"","sources":["../src/dot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,YAAY,EAAe,MAAM,eAAe,CAAC;AAG1D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAoCjD;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CACjB,OAA+B;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC;IACnC,OAAO,YAAY,CAAuB;QACxC,IAAI;QACJ,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,SAAS,CAAC,GAAG;YACX,GAAG,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,IAAI;YACF,MAAM,SAAS,GAAG,SAAS,CAAC;gBAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,OAAO,EACL,OAAO,CAAC,cAAc,KAAK,SAAS;oBAClC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE;oBAC5C,CAAC,CAAC,SAAS;aAChB,CAAC,CAAC;YACH,oEAAoE;YACpE,kEAAkE;YAClE,8DAA8D;YAC9D,0DAA0D;YAC1D,MAAM,SAAS,GAAG,SAAmD,CAAC;YACtE,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC;QAC1C,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"dot.js","sourceRoot":"","sources":["../src/dot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,GAAG,EAA6B,MAAM,eAAe,CAAC;AAG/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAwBjD;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CACjB,OAA+B;IAE/B,OAAO,GAAG,CAAC;QACT,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,OAAO;QAChB,SAAS,CAAC,GAAG;YACX,GAAG,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,IAAI;YACF,MAAM,SAAS,GAAG,SAAS,CAAC;gBAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,OAAO,EACL,OAAO,CAAC,cAAc,KAAK,SAAS;oBAClC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE;oBAC5C,CAAC,CAAC,SAAS;aAChB,CAAC,CAAC;YACH,oEAAoE;YACpE,kEAAkE;YAClE,8DAA8D;YAC9D,0DAA0D;YAC1D,MAAM,SAAS,GAAG,SAAmD,CAAC;YACtE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arki/env",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Type-safe environment variable parsing for ARKI — defineEnv() built on @t3-oss/env-core with Zod contracts for common variable shapes.",
5
5
  "license": "MIT",
6
6
  "repository": {