@slip-stream-kit/config 0.14.0 → 0.16.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/dist/entry/index.d.ts +1 -1
- package/dist/entry/internal.d.ts +3 -0
- package/dist/entry/vite.d.ts +1 -1
- package/dist/index.js.map +2 -2
- package/dist/internal.js +87 -16
- package/dist/internal.js.map +4 -4
- package/dist/lib/package-config/package-config-schema.d.ts +4 -0
- package/dist/lib/package-config/package-config.d.ts +18 -1
- package/dist/lib/release-slug/app-alias.d.ts +15 -0
- package/dist/lib/release-slug/release-slug.d.ts +2 -2
- package/dist/lib/release-slug/repo-slug.d.ts +29 -0
- package/dist/lib/vite/vite.d.ts +15 -2
- package/dist/playwright.js +81 -17
- package/dist/playwright.js.map +4 -4
- package/dist/vite.js +25 -2
- package/dist/vite.js.map +2 -2
- package/package.json +1 -1
- package/readme.md +15 -1
package/dist/entry/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { defineConfig } from '../lib/package-config/package-config';
|
|
2
|
-
export type { InfraKitDev, InfraKitDevProxy, InfraKitDevProxyRoute, InfraKitDevProxySource, InfraKitE2e, InfraKitPackageConfig, InfraKitPackageConfigInput, InfraKitPackageType, } from '../lib/package-config/package-config';
|
|
2
|
+
export type { InfraKitDev, InfraKitDevEnv, InfraKitDevProxy, InfraKitDevProxyRoute, InfraKitDevProxySource, InfraKitE2e, InfraKitPackageConfig, InfraKitPackageConfigInput, InfraKitPackageType, } from '../lib/package-config/package-config';
|
|
3
3
|
export { defineVendorConfig } from '../lib/vendor/config-schema';
|
|
4
4
|
export type { VendorConfig, VendorCopyItem } from '../lib/vendor/config-schema';
|
package/dist/entry/internal.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export { packageConfigSchema } from '../lib/package-config/package-config-schema';
|
|
2
2
|
export { DEV_SERVING_MARKER, E2E_MODE_ENV } from '../lib/playwright/playwright';
|
|
3
|
+
export { readAppAliasHost, readAppAliasName } from '../lib/release-slug/app-alias';
|
|
3
4
|
export { readRelease } from '../lib/release-slug/read-release';
|
|
4
5
|
export { DEFAULT_RELEASE_SLUG, slugifyHostLabel, slugifyRelease } from '../lib/release-slug/release-slug';
|
|
6
|
+
export { DEFAULT_REPO_SLUG, readRepoIdentity, readRepoSlug } from '../lib/release-slug/repo-slug';
|
|
7
|
+
export type { RepoIdentity } from '../lib/release-slug/repo-slug';
|
|
5
8
|
export { defineVendorConfig, VENDOR_CONFIG_FILE, vendorConfigSchema, vendorCopyItemSchema, } from '../lib/vendor/config-schema';
|
|
6
9
|
export type { VendorConfig, VendorCopyItem } from '../lib/vendor/config-schema';
|
|
7
10
|
export { describeProxyRoutes, DEV_CONTEXT_WIRE_VERSION, loadDev, loadPackageConfig, readCloudOrigin, readLocalContext, readLocalSet, } from '../lib/vite/vite';
|
package/dist/entry/vite.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { infraKitDev, infraKitProxy, resolveProxyConfig, slugifyRelease } from '../lib/vite/vite';
|
|
1
|
+
export { infraKitDev, infraKitProxy, loadPackageConfig, resolveProxyConfig, slugifyRelease } from '../lib/vite/vite';
|
|
2
2
|
export type { InfraKitBasicAuth, InfraKitDevOptions, InfraKitViteProxy, InfraKitViteProxyEntry } from '../lib/vite/vite';
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/lib/package-config/package-config.ts", "../src/lib/vendor/config-schema.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Validation rules for a single workspace package, declared in its\n * `infra-kit.config.ts`. Every field is optional: a key left unset falls back to\n * the active baseline, and a key set replaces that default wholesale (per-key, no\n * array concatenation) so a package can opt out with an explicit empty array.\n *\n * The baselines themselves (`DEFAULT_RULES` / `ROOT_DEFAULT_RULES`) deliberately do\n * NOT live here \u2014 they are audit POLICY, and policy belongs to the `infra-kit` CLI\n * that enforces it, not to the package a consumer installs to author a config.\n *\n * Most packages need none of these \u2014 the standard rules live in the baseline, so\n * a typical config is just `defineConfig(() => ({}))`.\n *\n * @example\n * // infra-kit.config.ts\n * import { defineConfig } from '@slip-stream-kit/config'\n *\n * export default defineConfig(() => ({}))\n */\nexport interface InfraKitPackageConfig {\n /** Scripts that must be present in the package's package.json `scripts` map. */\n requiredScripts?: string[]\n /** Files (relative to the package root) that must exist on disk. */\n requiredFiles?: string[]\n /** Turborepo expectations \u2014 only meaningful where a turbo.json lives (the root). */\n turbo?: {\n /** Tasks that must be defined in turbo.json `tasks`. */\n requiredTasks?: string[]\n }\n /**\n * The env var holding this app part's deployed URL, e.g. `CLIENT_URL`. The value lives in Doppler, per\n * environment \u2014 prod's host is not `<env>`-shaped, so no template in code can name it. The dev proxy sends\n * a UI's cloud routes there, and e2e runs against it in cloud mode. Required on a UI whose `dev.proxy`\n * has a route that can go to cloud, and on any `e2e.target`.\n */\n deployedUrlEnv?: string\n /** Local-dev configuration. Accepted-and-inert to the audit; consumed by the dev server. */\n dev?: InfraKitDev\n /** Which app part this e2e package tests. Consumed by `infraKitE2e()` and the CLI, inert to the audit. */\n e2e?: InfraKitE2e\n /**\n * Explicit override for infra-kit's directory/dependency-based package-type detection (used to\n * pick the agent guidance rendered into this package's `CLAUDE.md`). Detection already covers\n * both consumer repos untouched, so this is an escape hatch for the cases it gets wrong \u2014 leaving\n * it unset is never an error.\n *\n * **Ordering precondition:** the CLI's own pinned `packageConfigSchema` \u2014 not this package's\n * version \u2014 governs what a consumer's `infra-kit.config.ts` may contain, and it is a\n * `z.strictObject`. Only write `type` here once the CLI in use is a version that carries this\n * key; an older CLI rejects the key outright and skips the rest of that package's audit checks.\n *\n * @example\n * // infra-kit.config.ts\n * export default defineConfig(() => ({ type: 'frontend' }))\n */\n type?: InfraKitPackageType\n}\n\n/** Package kinds infra-kit's agent guidance renders type-specific rules for. */\nexport type InfraKitPackageType = 'frontend' | 'backend' | 'lib' | 'e2e' | 'mobile'\n\n/** A proxy route's allowed backend source. */\nexport type InfraKitDevProxySource = 'local' | 'cloud'\n\nexport interface InfraKitDevProxyRoute {\n /** Backend package this route targets when resolved locally. */\n packageName: string\n /** Capabilities this route can resolve to. Must be non-empty. */\n from: InfraKitDevProxySource[]\n /**\n * Source used when a local backend for this package isn't active. Required when\n * `from` lists more than one source; redundant (and omitted) for a single-source\n * route. When set, must be one of `from`.\n */\n default?: InfraKitDevProxySource\n}\n\nexport interface InfraKitDevProxy {\n /**\n * The local backend's URL template \u2014 `<release>`/`<packageName>` are substituted at dev time. A cloud route\n * goes to the package's `deployedUrlEnv` instead.\n */\n templates: {\n local: string\n }\n /** Path-prefix (e.g. `/api`, `/api/v1`, `/media`) \u2192 route definition. */\n routes: Record<string, InfraKitDevProxyRoute>\n}\n\nexport interface InfraKitDev {\n proxy?: InfraKitDevProxy\n}\n\n/**\n * The e2e package's target. `infraKitE2e()` (`@slip-stream-kit/config/playwright`) reads it: a run is local\n * by default \u2014 `target` on this worktree, served by `infra-kit dev <app>` \u2014 and cloud only when asked\n * (`INFRA_KIT_E2E=cloud`, or CI), against the URL in the target package's `deployedUrlEnv`.\n *\n * @example\n * // apps/client/tests/infra-kit.config.ts\n * export default defineConfig(() => ({ e2e: { target: 'client/ui' } }))\n */\nexport interface InfraKitE2e {\n /** The package under test, `<app>/ui` or `<app>/api`. */\n target: string\n}\n\n/**\n * Accepted shapes for a package config's default export \u2014 mirrors Vite's\n * `defineConfig` input: a plain object, a sync factory, or an async factory.\n */\nexport type InfraKitPackageConfigInput =\n InfraKitPackageConfig | (() => InfraKitPackageConfig) | (() => Promise<InfraKitPackageConfig>)\n\n/**\n * Identity helper that gives `infra-kit.config.ts` authors full type inference\n * and editor autocomplete without changing the value \u2014 exactly like Vite's\n * `defineConfig`. Resolution of the factory form happens in the CLI's loader, not here.\n *\n * @example\n * export default defineConfig(() => ({}))\n * @example\n * export default defineConfig(() => ({ requiredScripts: [] }))\n */\nexport const defineConfig = (config: InfraKitPackageConfigInput): InfraKitPackageConfigInput => {\n return config\n}\n", "import { z } from 'zod'\n\n/**\n * Pure (node-free) vendor config schema + authoring helper. Kept separate from\n * `config.ts` (which imports node builtins for the runtime loader) so the public\n * lib entry can re-export `defineVendorConfig` without dragging node types into\n * the emitted `.d.ts`.\n */\n\n/**\n * Filename a source repo provides at its root to declare WHAT `vendor sync`\n * copies (`copy[]`). Lives ONLY on the write path \u2014 `vendor check` never loads it.\n * WHERE/WHICH to stamp (`workspaceDir` + `targets`) is machine-local and lives in\n * the user-global factory config (`~/.infra-kit/vendor.json`).\n */\nexport const VENDOR_CONFIG_FILE = 'vendor.config.ts'\n\n/**\n * A non-empty, repo-relative path with no `..` segments and no absolute prefix\n * (POSIX `/`, UNC/`\\`, or a Windows drive like `C:`). Containment guard for\n * vendor copy items so a malicious/typo config can't read or write outside the\n * source/target repo roots. Kept as a string/regex check (no `node:path`) to\n * respect this file's node-free constraint \u2014 `sync-ops.ts` does the resolved\n * runtime containment assert as defense in depth.\n */\nconst safeRelPath = z.string().refine(\n (p) => {\n const isAbsolute = /^(?:[/\\\\]|[a-z]:)/i.test(p)\n const hasDotDotSegment = p.split(/[\\\\/]/).includes('..')\n\n return !isAbsolute && !hasDotDotSegment && p.trim().length > 0\n },\n { message: 'must be a non-empty repo-relative path without \"..\" segments' },\n)\n\n/**\n * One item to sync from the source repo into each target. `vendored: true` marks\n * workspace packages that must land under `vendor/` (the single-source-of-truth\n * code); everything else is root-level tooling that stays at the repo root.\n */\nexport const vendorCopyItemSchema = z.object({\n name: z.string(),\n source: safeRelPath,\n target: safeRelPath,\n type: z.enum(['file', 'directory']),\n vendored: z.boolean().optional(),\n})\n\nexport const vendorConfigSchema = z\n .object({\n /** Files/dirs to copy. Items with `vendored: true` land under `vendor/`. */\n copy: z.array(vendorCopyItemSchema),\n })\n // Reject stray keys so a leftover `targets` (now machine-local, in\n // ~/.infra-kit/vendor.json) yields a clear \"unrecognized key\" error rather\n // than being silently ignored.\n .strict()\n\nexport type VendorCopyItem = z.infer<typeof vendorCopyItemSchema>\nexport type VendorConfig = z.infer<typeof vendorConfigSchema>\n\n/**\n * Identity helper for authoring a type-safe `vendor.config.ts` in a source repo.\n * Re-exported from the public lib entry so a source repo can\n * `import { defineVendorConfig } from 'infra-kit'`.\n *\n * NOTE: a `vendor.config.ts` must be type-strippable \u2014 Node's native type\n * stripping (Node >= 24) loads it without a build step, which forbids `enum`,\n * `namespace`, and parameter properties.\n *\n * @example\n * export default defineVendorConfig({\n * copy: [{ name: 'Configs', source: 'vendor/configs', target: 'vendor/configs', type: 'directory', vendored: true }],\n * })\n */\nexport const defineVendorConfig = (config: VendorConfig): VendorConfig => {\n return config\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["/**\n * Validation rules for a single workspace package, declared in its\n * `infra-kit.config.ts`. Every field is optional: a key left unset falls back to\n * the active baseline, and a key set replaces that default wholesale (per-key, no\n * array concatenation) so a package can opt out with an explicit empty array.\n *\n * The baselines themselves (`DEFAULT_RULES` / `ROOT_DEFAULT_RULES`) deliberately do\n * NOT live here \u2014 they are audit POLICY, and policy belongs to the `infra-kit` CLI\n * that enforces it, not to the package a consumer installs to author a config.\n *\n * Most packages need none of these \u2014 the standard rules live in the baseline, so\n * a typical config is just `defineConfig(() => ({}))`.\n *\n * @example\n * // infra-kit.config.ts\n * import { defineConfig } from '@slip-stream-kit/config'\n *\n * export default defineConfig(() => ({}))\n */\nexport interface InfraKitPackageConfig {\n /** Scripts that must be present in the package's package.json `scripts` map. */\n requiredScripts?: string[]\n /** Files (relative to the package root) that must exist on disk. */\n requiredFiles?: string[]\n /** Turborepo expectations \u2014 only meaningful where a turbo.json lives (the root). */\n turbo?: {\n /** Tasks that must be defined in turbo.json `tasks`. */\n requiredTasks?: string[]\n }\n /**\n * The env var holding this app part's deployed URL, e.g. `CLIENT_URL`. The value lives in Doppler, per\n * environment \u2014 prod's host is not `<env>`-shaped, so no template in code can name it. The dev proxy sends\n * a UI's cloud routes there, and e2e runs against it in cloud mode. Required on a UI whose `dev.proxy`\n * has a route that can go to cloud, and on any `e2e.target`.\n */\n deployedUrlEnv?: string\n /** Local-dev configuration. Accepted-and-inert to the audit; consumed by the dev server. */\n dev?: InfraKitDev\n /** Which app part this e2e package tests. Consumed by `infraKitE2e()` and the CLI, inert to the audit. */\n e2e?: InfraKitE2e\n /**\n * Explicit override for infra-kit's directory/dependency-based package-type detection (used to\n * pick the agent guidance rendered into this package's `CLAUDE.md`). Detection already covers\n * both consumer repos untouched, so this is an escape hatch for the cases it gets wrong \u2014 leaving\n * it unset is never an error.\n *\n * **Ordering precondition:** the CLI's own pinned `packageConfigSchema` \u2014 not this package's\n * version \u2014 governs what a consumer's `infra-kit.config.ts` may contain, and it is a\n * `z.strictObject`. Only write `type` here once the CLI in use is a version that carries this\n * key; an older CLI rejects the key outright and skips the rest of that package's audit checks.\n *\n * @example\n * // infra-kit.config.ts\n * export default defineConfig(() => ({ type: 'frontend' }))\n */\n type?: InfraKitPackageType\n}\n\n/** Package kinds infra-kit's agent guidance renders type-specific rules for. */\nexport type InfraKitPackageType = 'frontend' | 'backend' | 'lib' | 'e2e' | 'mobile'\n\n/** A proxy route's allowed backend source. */\nexport type InfraKitDevProxySource = 'local' | 'cloud'\n\nexport interface InfraKitDevProxyRoute {\n /** Backend package this route targets when resolved locally. */\n packageName: string\n /** Capabilities this route can resolve to. Must be non-empty. */\n from: InfraKitDevProxySource[]\n /**\n * Source used when a local backend for this package isn't active. Required when\n * `from` lists more than one source; redundant (and omitted) for a single-source\n * route. When set, must be one of `from`.\n */\n default?: InfraKitDevProxySource\n}\n\nexport interface InfraKitDevProxy {\n /**\n * The local backend's URL template \u2014 `<release>`/`<packageName>` are substituted at dev time. A cloud route\n * goes to the package's `deployedUrlEnv` instead. Consulted only for a fragment from a pre-v2 CLI: a\n * current one publishes the exact `origin` (`<release>.<packageName>.<repo>.localhost`) it registered.\n */\n templates: {\n local: string\n }\n /** Path-prefix (e.g. `/api`, `/api/v1`, `/media`) \u2192 route definition. */\n routes: Record<string, InfraKitDevProxyRoute>\n}\n\nexport interface InfraKitDev {\n proxy?: InfraKitDevProxy\n env?: InfraKitDevEnv\n}\n\n/**\n * Env overrides for this package's dev server only, applied over the loaded (Doppler) env when vite starts\n * it \u2014 never on `build`. For variables another build mode needs that break local dev, e.g. a mobile-only\n * absolute origin that sends requests around the dev proxy.\n *\n * @example\n * // apps/client/ui/infra-kit.config.ts\n * export default defineConfig(() => ({ dev: { env: { unset: ['VITE_ORIGIN_DOMAIN'] } } }))\n */\nexport interface InfraKitDevEnv {\n /** Variables removed from the dev server's env. */\n unset?: string[]\n /** Variables set (or overridden) in the dev server's env. A name cannot also be in `unset`. */\n set?: Record<string, string>\n}\n\n/**\n * The e2e package's target. `infraKitE2e()` (`@slip-stream-kit/config/playwright`) reads it: a run is local\n * by default \u2014 `target` on this worktree, served by `infra-kit dev <app>` \u2014 and cloud only when asked\n * (`INFRA_KIT_E2E=cloud`, or CI), against the URL in the target package's `deployedUrlEnv`.\n *\n * @example\n * // apps/client/tests/infra-kit.config.ts\n * export default defineConfig(() => ({ e2e: { target: 'client/ui' } }))\n */\nexport interface InfraKitE2e {\n /** The package under test, `<app>/ui` or `<app>/api`. */\n target: string\n}\n\n/**\n * Accepted shapes for a package config's default export \u2014 mirrors Vite's\n * `defineConfig` input: a plain object, a sync factory, or an async factory.\n */\nexport type InfraKitPackageConfigInput =\n InfraKitPackageConfig | (() => InfraKitPackageConfig) | (() => Promise<InfraKitPackageConfig>)\n\n/**\n * Identity helper that gives `infra-kit.config.ts` authors full type inference\n * and editor autocomplete without changing the value \u2014 exactly like Vite's\n * `defineConfig`. Resolution of the factory form happens in the CLI's loader, not here.\n *\n * @example\n * export default defineConfig(() => ({}))\n * @example\n * export default defineConfig(() => ({ requiredScripts: [] }))\n */\nexport const defineConfig = (config: InfraKitPackageConfigInput): InfraKitPackageConfigInput => {\n return config\n}\n", "import { z } from 'zod'\n\n/**\n * Pure (node-free) vendor config schema + authoring helper. Kept separate from\n * `config.ts` (which imports node builtins for the runtime loader) so the public\n * lib entry can re-export `defineVendorConfig` without dragging node types into\n * the emitted `.d.ts`.\n */\n\n/**\n * Filename a source repo provides at its root to declare WHAT `vendor sync`\n * copies (`copy[]`). Lives ONLY on the write path \u2014 `vendor check` never loads it.\n * WHERE/WHICH to stamp (`workspaceDir` + `targets`) is machine-local and lives in\n * the user-global factory config (`~/.infra-kit/vendor.json`).\n */\nexport const VENDOR_CONFIG_FILE = 'vendor.config.ts'\n\n/**\n * A non-empty, repo-relative path with no `..` segments and no absolute prefix\n * (POSIX `/`, UNC/`\\`, or a Windows drive like `C:`). Containment guard for\n * vendor copy items so a malicious/typo config can't read or write outside the\n * source/target repo roots. Kept as a string/regex check (no `node:path`) to\n * respect this file's node-free constraint \u2014 `sync-ops.ts` does the resolved\n * runtime containment assert as defense in depth.\n */\nconst safeRelPath = z.string().refine(\n (p) => {\n const isAbsolute = /^(?:[/\\\\]|[a-z]:)/i.test(p)\n const hasDotDotSegment = p.split(/[\\\\/]/).includes('..')\n\n return !isAbsolute && !hasDotDotSegment && p.trim().length > 0\n },\n { message: 'must be a non-empty repo-relative path without \"..\" segments' },\n)\n\n/**\n * One item to sync from the source repo into each target. `vendored: true` marks\n * workspace packages that must land under `vendor/` (the single-source-of-truth\n * code); everything else is root-level tooling that stays at the repo root.\n */\nexport const vendorCopyItemSchema = z.object({\n name: z.string(),\n source: safeRelPath,\n target: safeRelPath,\n type: z.enum(['file', 'directory']),\n vendored: z.boolean().optional(),\n})\n\nexport const vendorConfigSchema = z\n .object({\n /** Files/dirs to copy. Items with `vendored: true` land under `vendor/`. */\n copy: z.array(vendorCopyItemSchema),\n })\n // Reject stray keys so a leftover `targets` (now machine-local, in\n // ~/.infra-kit/vendor.json) yields a clear \"unrecognized key\" error rather\n // than being silently ignored.\n .strict()\n\nexport type VendorCopyItem = z.infer<typeof vendorCopyItemSchema>\nexport type VendorConfig = z.infer<typeof vendorConfigSchema>\n\n/**\n * Identity helper for authoring a type-safe `vendor.config.ts` in a source repo.\n * Re-exported from the public lib entry so a source repo can\n * `import { defineVendorConfig } from 'infra-kit'`.\n *\n * NOTE: a `vendor.config.ts` must be type-strippable \u2014 Node's native type\n * stripping (Node >= 24) loads it without a build step, which forbids `enum`,\n * `namespace`, and parameter properties.\n *\n * @example\n * export default defineVendorConfig({\n * copy: [{ name: 'Configs', source: 'vendor/configs', target: 'vendor/configs', type: 'directory', vendored: true }],\n * })\n */\nexport const defineVendorConfig = (config: VendorConfig): VendorConfig => {\n return config\n}\n"],
|
|
5
|
+
"mappings": ";AA8IO,IAAM,eAAe,CAAC,WAAmE;AAC9F,SAAO;AACT;;;AChJA,SAAS,SAAS;AAyBlB,IAAM,cAAc,EAAE,OAAO,EAAE;AAAA,EAC7B,CAAC,MAAM;AACL,UAAM,aAAa,qBAAqB,KAAK,CAAC;AAC9C,UAAM,mBAAmB,EAAE,MAAM,OAAO,EAAE,SAAS,IAAI;AAEvD,WAAO,CAAC,cAAc,CAAC,oBAAoB,EAAE,KAAK,EAAE,SAAS;AAAA,EAC/D;AAAA,EACA,EAAE,SAAS,+DAA+D;AAC5E;AAOO,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,MAAM,EAAE,OAAO;AAAA,EACf,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM,EAAE,KAAK,CAAC,QAAQ,WAAW,CAAC;AAAA,EAClC,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAEM,IAAM,qBAAqB,EAC/B,OAAO;AAAA;AAAA,EAEN,MAAM,EAAE,MAAM,oBAAoB;AACpC,CAAC,EAIA,OAAO;AAmBH,IAAM,qBAAqB,CAAC,WAAuC;AACxE,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/internal.js
CHANGED
|
@@ -51,7 +51,18 @@ var packageConfigSchema = z.strictObject({
|
|
|
51
51
|
}
|
|
52
52
|
)
|
|
53
53
|
)
|
|
54
|
-
}).optional()
|
|
54
|
+
}).optional(),
|
|
55
|
+
env: z.strictObject({
|
|
56
|
+
unset: z.array(z.string().regex(ENV_VAR_NAME, "dev.env.unset entries must be env var names")).optional(),
|
|
57
|
+
set: z.record(z.string().regex(ENV_VAR_NAME, "dev.env.set keys must be env var names"), z.string()).optional()
|
|
58
|
+
}).refine(
|
|
59
|
+
(env) => {
|
|
60
|
+
return !env.unset?.some((name) => {
|
|
61
|
+
return env.set?.[name] !== void 0;
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
{ message: "a variable cannot be in both `dev.env.unset` and `dev.env.set`" }
|
|
65
|
+
).optional()
|
|
55
66
|
}).optional(),
|
|
56
67
|
e2e: z.strictObject({
|
|
57
68
|
target: z.string().regex(/^[^/\s]+\/(?:ui|api)$/, "target must be `<app>/ui` or `<app>/api` (e.g. `client/ui`)"),
|
|
@@ -77,9 +88,11 @@ var packageConfigSchema = z.strictObject({
|
|
|
77
88
|
import { execFileSync } from "node:child_process";
|
|
78
89
|
|
|
79
90
|
// src/lib/release-slug/release-slug.ts
|
|
91
|
+
var MAX_DNS_LABEL_LENGTH = 63;
|
|
80
92
|
var slugifyHostLabel = (label) => {
|
|
81
93
|
const runs = label.toLowerCase().match(/[a-z0-9]+/g);
|
|
82
|
-
|
|
94
|
+
const capped = runs ? runs.join("-").slice(0, MAX_DNS_LABEL_LENGTH) : "";
|
|
95
|
+
return capped.endsWith("-") ? capped.slice(0, -1) : capped;
|
|
83
96
|
};
|
|
84
97
|
var slugifyRelease = (branch) => {
|
|
85
98
|
return slugifyHostLabel(branch.replace(/^(?:feature|feat|release|hotfix|bugfix|fix|chore)\//i, ""));
|
|
@@ -100,15 +113,66 @@ var readRelease = (cwd) => {
|
|
|
100
113
|
}
|
|
101
114
|
};
|
|
102
115
|
|
|
103
|
-
// src/lib/
|
|
116
|
+
// src/lib/release-slug/repo-slug.ts
|
|
117
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
104
118
|
import fs from "node:fs";
|
|
105
119
|
import path from "node:path";
|
|
120
|
+
var DEFAULT_REPO_SLUG = "repo";
|
|
121
|
+
var readConfiguredRepoSlug = (root) => {
|
|
122
|
+
try {
|
|
123
|
+
const config = JSON.parse(fs.readFileSync(path.join(root, "infra-kit.json"), "utf-8"));
|
|
124
|
+
const aliasRepo = config?.aliasRepo;
|
|
125
|
+
return typeof aliasRepo === "string" ? slugifyHostLabel(aliasRepo) : "";
|
|
126
|
+
} catch {
|
|
127
|
+
return "";
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
var readRepoIdentity = (cwd) => {
|
|
131
|
+
let commonDir;
|
|
132
|
+
try {
|
|
133
|
+
commonDir = execFileSync2("git", ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
|
|
134
|
+
cwd,
|
|
135
|
+
encoding: "utf-8",
|
|
136
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
137
|
+
}).trim();
|
|
138
|
+
} catch {
|
|
139
|
+
return { root: null, slug: DEFAULT_REPO_SLUG };
|
|
140
|
+
}
|
|
141
|
+
const name = path.basename(commonDir);
|
|
142
|
+
if (commonDir.includes(`${path.sep}.git${path.sep}modules${path.sep}`)) {
|
|
143
|
+
return { root: null, slug: slugifyHostLabel(name) || DEFAULT_REPO_SLUG };
|
|
144
|
+
}
|
|
145
|
+
const root = name.startsWith(".") ? path.dirname(commonDir) : commonDir;
|
|
146
|
+
return {
|
|
147
|
+
root,
|
|
148
|
+
slug: readConfiguredRepoSlug(root) || slugifyHostLabel(path.basename(root).replace(/\.git$/, "")) || DEFAULT_REPO_SLUG
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
var readRepoSlug = (cwd) => {
|
|
152
|
+
return readRepoIdentity(cwd).slug;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// src/lib/release-slug/app-alias.ts
|
|
156
|
+
var readAppAliasName = (packageName, appDir) => {
|
|
157
|
+
const label = slugifyHostLabel(packageName);
|
|
158
|
+
if (label === "") {
|
|
159
|
+
throw new Error(`infra-kit: package name "${packageName}" has no letters or digits to build a hostname from.`);
|
|
160
|
+
}
|
|
161
|
+
return `${readRelease(appDir)}.${label}.${readRepoSlug(appDir)}`;
|
|
162
|
+
};
|
|
163
|
+
var readAppAliasHost = (packageName, appDir) => {
|
|
164
|
+
return `${readAppAliasName(packageName, appDir)}.localhost`;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/lib/vite/vite.ts
|
|
168
|
+
import fs2 from "node:fs";
|
|
169
|
+
import path2 from "node:path";
|
|
106
170
|
import process from "node:process";
|
|
107
171
|
import { pathToFileURL } from "node:url";
|
|
108
172
|
import { z as z2 } from "zod";
|
|
109
173
|
var PACKAGE_CONFIG_FILE = "infra-kit.config.ts";
|
|
110
|
-
var DEV_CONTEXT_DIR =
|
|
111
|
-
var DEV_CONTEXT_FILE =
|
|
174
|
+
var DEV_CONTEXT_DIR = path2.join(".infra-kit", "dev-context");
|
|
175
|
+
var DEV_CONTEXT_FILE = path2.join(".infra-kit", "dev-context.json");
|
|
112
176
|
var devContextFragmentSchema = z2.object({
|
|
113
177
|
package: z2.string(),
|
|
114
178
|
port: z2.number(),
|
|
@@ -163,6 +227,8 @@ var resolveLocalTarget = (args) => {
|
|
|
163
227
|
// The local template resolves to a `<release>.<packageName>.localhost` alias the dev-server
|
|
164
228
|
// registered with portless — which slugifies the package name to a legal DNS label. Slugify
|
|
165
229
|
// identically here or a scoped name (`@hulyo/client-ui`) emits a target that no alias backs.
|
|
230
|
+
// There is no `<repo>` token on purpose: only a pre-v2 CLI writes an origin-less fragment, and that
|
|
231
|
+
// CLI registered its aliases without a repo label, so the legacy template is exact for it.
|
|
166
232
|
packageName: slugifyHostLabel(route.packageName),
|
|
167
233
|
env: env ?? ""
|
|
168
234
|
});
|
|
@@ -216,9 +282,9 @@ var readCloudOrigin = (envVar, env = process.env) => {
|
|
|
216
282
|
return { envVar, url: envVar ? env[envVar] || void 0 : void 0 };
|
|
217
283
|
};
|
|
218
284
|
var loadPackageConfig = async (cwd) => {
|
|
219
|
-
const configPath =
|
|
220
|
-
if (!
|
|
221
|
-
const stat =
|
|
285
|
+
const configPath = path2.join(cwd, PACKAGE_CONFIG_FILE);
|
|
286
|
+
if (!fs2.existsSync(configPath)) return void 0;
|
|
287
|
+
const stat = fs2.statSync(configPath);
|
|
222
288
|
const moduleUrl = `${pathToFileURL(configPath).href}?mtime=${Number(stat.mtimeMs)}`;
|
|
223
289
|
const imported = await import(moduleUrl);
|
|
224
290
|
const rawExport = imported.default;
|
|
@@ -234,7 +300,7 @@ var loadPackageConfig = async (cwd) => {
|
|
|
234
300
|
};
|
|
235
301
|
var loadDev = async (cwd) => {
|
|
236
302
|
const dev = (await loadPackageConfig(cwd))?.dev;
|
|
237
|
-
warnIfNonHttpsLocalTemplate(dev,
|
|
303
|
+
warnIfNonHttpsLocalTemplate(dev, path2.join(cwd, PACKAGE_CONFIG_FILE));
|
|
238
304
|
return dev;
|
|
239
305
|
};
|
|
240
306
|
var extractPackages = (parsed) => {
|
|
@@ -254,11 +320,11 @@ var extractPackages = (parsed) => {
|
|
|
254
320
|
return [];
|
|
255
321
|
};
|
|
256
322
|
var findUp = (start, relative) => {
|
|
257
|
-
let dir =
|
|
323
|
+
let dir = path2.resolve(start);
|
|
258
324
|
for (; ; ) {
|
|
259
|
-
const candidate =
|
|
260
|
-
if (
|
|
261
|
-
const parent =
|
|
325
|
+
const candidate = path2.join(dir, relative);
|
|
326
|
+
if (fs2.existsSync(candidate)) return candidate;
|
|
327
|
+
const parent = path2.dirname(dir);
|
|
262
328
|
if (parent === dir) return void 0;
|
|
263
329
|
dir = parent;
|
|
264
330
|
}
|
|
@@ -278,7 +344,7 @@ var isFragmentWriterAlive = (pid) => {
|
|
|
278
344
|
var readFragmentDir = (dir) => {
|
|
279
345
|
let entries;
|
|
280
346
|
try {
|
|
281
|
-
entries =
|
|
347
|
+
entries = fs2.readdirSync(dir);
|
|
282
348
|
} catch {
|
|
283
349
|
return emptyLocalContext();
|
|
284
350
|
}
|
|
@@ -287,7 +353,7 @@ var readFragmentDir = (dir) => {
|
|
|
287
353
|
for (const name of entries) {
|
|
288
354
|
if (!name.endsWith(".json")) continue;
|
|
289
355
|
try {
|
|
290
|
-
const parsed = devContextFragmentSchema.safeParse(JSON.parse(
|
|
356
|
+
const parsed = devContextFragmentSchema.safeParse(JSON.parse(fs2.readFileSync(path2.join(dir, name), "utf-8")));
|
|
291
357
|
if (!parsed.success) continue;
|
|
292
358
|
if (!isFragmentWriterAlive(parsed.data.pid)) continue;
|
|
293
359
|
packages.add(parsed.data.package);
|
|
@@ -311,7 +377,7 @@ var readLocalContext = (cwd) => {
|
|
|
311
377
|
const legacy = findUp(cwd, DEV_CONTEXT_FILE);
|
|
312
378
|
if (!legacy) return emptyLocalContext();
|
|
313
379
|
try {
|
|
314
|
-
return { packages: new Set(extractPackages(JSON.parse(
|
|
380
|
+
return { packages: new Set(extractPackages(JSON.parse(fs2.readFileSync(legacy, "utf-8")))), info: /* @__PURE__ */ new Map() };
|
|
315
381
|
} catch {
|
|
316
382
|
return emptyLocalContext();
|
|
317
383
|
}
|
|
@@ -351,6 +417,7 @@ var defineVendorConfig = (config) => {
|
|
|
351
417
|
};
|
|
352
418
|
export {
|
|
353
419
|
DEFAULT_RELEASE_SLUG,
|
|
420
|
+
DEFAULT_REPO_SLUG,
|
|
354
421
|
DEV_CONTEXT_WIRE_VERSION,
|
|
355
422
|
DEV_SERVING_MARKER,
|
|
356
423
|
E2E_MODE_ENV,
|
|
@@ -360,10 +427,14 @@ export {
|
|
|
360
427
|
loadDev,
|
|
361
428
|
loadPackageConfig,
|
|
362
429
|
packageConfigSchema,
|
|
430
|
+
readAppAliasHost,
|
|
431
|
+
readAppAliasName,
|
|
363
432
|
readCloudOrigin,
|
|
364
433
|
readLocalContext,
|
|
365
434
|
readLocalSet,
|
|
366
435
|
readRelease,
|
|
436
|
+
readRepoIdentity,
|
|
437
|
+
readRepoSlug,
|
|
367
438
|
slugifyHostLabel,
|
|
368
439
|
slugifyRelease,
|
|
369
440
|
vendorConfigSchema,
|