primitive-app 3.2.0-alpha.6 → 3.2.0-alpha.7
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.
|
@@ -40,6 +40,24 @@ export declare const MIGRATION_GUIDE_SLUG = "getting-started/cli-project-migrati
|
|
|
40
40
|
* the document that says what to move where.
|
|
41
41
|
*/
|
|
42
42
|
export declare function staleLayoutMessage(detail: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* The one refusal for a command run outside a Primitive project (#3154,
|
|
45
|
+
* intent criterion 5).
|
|
46
|
+
*
|
|
47
|
+
* There is exactly one way to resolve the configuration tree, the credentials
|
|
48
|
+
* and the app: the environment named by `primitive/config.json`. Outside a
|
|
49
|
+
* project there is no such thing, and the CLI says so once, in these words,
|
|
50
|
+
* wherever the question is asked — the resolver core, the CLI's
|
|
51
|
+
* `requireCurrentEnvironment()`, and the credentials store.
|
|
52
|
+
*
|
|
53
|
+
* Two constraints on the wording, both test-asserted:
|
|
54
|
+
*
|
|
55
|
+
* - it names `primitive init`, the one command that creates what is missing;
|
|
56
|
+
* - it never names `primitive env add`, which after this change also fails
|
|
57
|
+
* outside a project — an error may only offer an invocation it does not
|
|
58
|
+
* itself block.
|
|
59
|
+
*/
|
|
60
|
+
export declare function missingConfigMessage(where: string): string;
|
|
43
61
|
/**
|
|
44
62
|
* Error kinds callers branch on. Every failure is one of these — no reader is
|
|
45
63
|
* ever left guessing what a broken config meant.
|
|
@@ -65,6 +65,6 @@ const observer = new MutationObserver(async (mutations, obs) => {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
68
|
-
`},transformIndexHtml(e){if(!h||!d)return e;let t=`<style data-primitive-devtools-sonner>${g}</style>`;return e.replace(`</body>`,`${t}\n<script type="module" src="/@id/__x00__virtual:primitive-devtools-init"><\/script>\n</body>`)},hotUpdate({file:e,server:t}){if(e.endsWith(`.primitive-test.ts`)){let e=t.moduleGraph.getModuleById(c);e&&(t.moduleGraph.invalidateModule(e),t.ws.send({type:`full-reload`}))}}}}var f=`primitive`,p=`.primitive`,m=`config.json`,h=`local.json`,g=`primitive/config.json`,_=`.primitive/local.json`,v=`getting-started/cli-project-migration`;function y(e){return`${e} The Primitive configuration tree moved out of the hidden directory: the config is now ${g} and each environment's TOML is at primitive/<env>/, while .primitive/ keeps only machine-local state. Nothing is read from either tree until the project is migrated — follow ${v}.`}var
|
|
69
|
-
`)}function
|
|
70
|
-
`)}function
|
|
68
|
+
`},transformIndexHtml(e){if(!h||!d)return e;let t=`<style data-primitive-devtools-sonner>${g}</style>`;return e.replace(`</body>`,`${t}\n<script type="module" src="/@id/__x00__virtual:primitive-devtools-init"><\/script>\n</body>`)},hotUpdate({file:e,server:t}){if(e.endsWith(`.primitive-test.ts`)){let e=t.moduleGraph.getModuleById(c);e&&(t.moduleGraph.invalidateModule(e),t.ws.send({type:`full-reload`}))}}}}var f=`primitive`,p=`.primitive`,m=`config.json`,h=`local.json`,g=`primitive/config.json`,_=`.primitive/local.json`,v=`getting-started/cli-project-migration`;function y(e){return`${e} The Primitive configuration tree moved out of the hidden directory: the config is now ${g} and each environment's TOML is at primitive/<env>/, while .primitive/ keeps only machine-local state. Nothing is read from either tree until the project is migrated — follow ${v}.`}function b(e){return`No ${g} found in ${e} or any parent directory. Primitive commands run inside a Primitive project: it is where the CLI reads the environment, the app that environment names, and the configuration tree from. Run 'primitive init' to create one.`}var x=class extends Error{kind;path;constructor(e,t,n){super(t),this.name=`PrimitiveEnvError`,this.kind=e,this.path=n}};function S(e){if(typeof e!=`string`)return;let t=e.trim();if(!t)return;let n;try{n=new URL(t)}catch{return}if(!(n.protocol!==`https:`&&n.protocol!==`http:`)&&!(n.protocol===`http:`&&n.hostname!==`localhost`&&n.hostname!==`127.0.0.1`)&&!(n.username||n.password)&&!(n.pathname!==`/`&&n.pathname!==``)&&!(n.search||n.hash))return n.origin}function C(e,t){return`Environment "${e}" in ${t?`${g} (${t})`:g} has no "appId". Every environment names exactly one app — add "appId": "<app-id>" to that environment in ${g}. Find the app id in the Primitive admin UI, with 'primitive apps list' run from another Primitive project, or as the residual "currentAppId" in .primitive/credentials.json if this environment was ever pointed at an app by the retired per-machine app selection.`}function w(e){if(typeof e==`string`)return e.trim()||void 0}function T(e){return e.startsWith(`https://`)?`wss://`+e.slice(8):e.startsWith(`http://`)?`ws://`+e.slice(7):e}function E(e){let n=(0,a.join)(e,p,m);if((0,t.existsSync)(n))throw new x(`stale-layout`,y(`${n} still exists.`),n);let r=(0,a.join)(e,p,`sync`);if((0,t.existsSync)(r))throw new x(`stale-layout`,y(`${r} still exists.`),r)}function D(e={}){let n=(e.env??process.env).PRIMITIVE_PROJECT_CONFIG;if(n){let e=(0,a.resolve)(n);if((0,a.basename)((0,a.dirname)(e))===`.primitive`)throw new x(`stale-layout`,y(`PRIMITIVE_PROJECT_CONFIG points at ${e}, inside a ${p}/ directory.`),e);return(0,t.existsSync)(e)?(E(O(e)),e):null}let r=(0,a.resolve)(e.cwd??process.cwd());for(;;){let e=(0,a.join)(r,f,m);if(E(r),(0,t.existsSync)(e))return e;let n=(0,a.dirname)(r);if(n===r)return null;r=n}}function O(e){let t=(0,a.dirname)(e);return(0,a.basename)(t)===`primitive`?(0,a.dirname)(t):t}function k(e){return(0,a.join)(O(e),p,h)}function A(e){if(!(0,t.existsSync)(e))throw new x(`missing-config`,b((0,a.dirname)(e)),e);let n;try{n=(0,t.readFileSync)(e,`utf-8`)}catch(t){throw new x(`malformed-config`,`Failed to read ${g} (${e}): ${t.message}`,e)}let r;try{r=JSON.parse(n)}catch(t){throw new x(`malformed-config`,`Failed to parse ${g} (${e}): ${t.message}`,e)}if(!r||typeof r!=`object`||Array.isArray(r))throw new x(`malformed-config`,`${g} (${e}) must contain a JSON object at the top level.`,e);let i=r;if(typeof i.version!=`number`||!Number.isInteger(i.version))throw new x(`malformed-config`,`${g} (${e}) is missing required integer field "version".`,e);if(i.version!==1)throw new x(`unsupported-version`,`${g} (${e}) has version ${i.version}, but this tool understands version 1.`,e);if(!i.environments||typeof i.environments!=`object`||Array.isArray(i.environments))throw new x(`malformed-config`,`${g} (${e}) is missing required "environments" object.`,e);let o={};for(let[t,n]of Object.entries(i.environments)){if(!n||typeof n!=`object`||Array.isArray(n))throw new x(`malformed-config`,`Environment "${t}" must be an object in ${g} (${e}).`,e);let r=n;if(typeof r.apiUrl!=`string`||!r.apiUrl)throw new x(`malformed-config`,`Environment "${t}" must have a non-empty "apiUrl" string in ${g} (${e}).`,e);let i=w(r.appId);if(!i)throw new x(`missing-app-id`,C(t,e),e);o[t]={apiUrl:r.apiUrl.replace(/\/$/,``),appId:i,appName:typeof r.appName==`string`?r.appName:void 0,webUrl:S(r.webUrl),description:typeof r.description==`string`?r.description:void 0}}return{version:i.version,defaultEnvironment:typeof i.defaultEnvironment==`string`&&i.defaultEnvironment?i.defaultEnvironment:void 0,environments:o}}function j(e){let n=k(e);if(!(0,t.existsSync)(n))return null;let r=e=>{throw new x(`corrupt-local-state`,`${_} (${n}) is unreadable: ${e}. Delete the file or re-run 'primitive env use <name>'.`,n)},i;try{i=JSON.parse((0,t.readFileSync)(n,`utf-8`))}catch(e){return r(e.message)}if(!i||typeof i!=`object`||Array.isArray(i))return r(`expected a JSON object`);let a=i.selectedEnvironment;return a==null||a===``?null:typeof a==`string`?a:r(`"selectedEnvironment" must be a string`)}function M(e,t){let n=Object.keys(e.environments),r=n.join(`, `)||`(none)`,i=t.configPath?`${g} (${t.configPath})`:g,a=(n,a,o)=>{if(!e.environments[n])throw new x(`unknown-environment`,`Environment "${n}" is not defined in ${i} (selected ${o}). Available: ${r}`,t.configPath);return{name:n,source:a}};if(t.explicitEnvName)return a(t.explicitEnvName,`explicit`,`explicitly`);if(t.envVarName)return a(t.envVarName,`env-var`,`via PRIMITIVE_ENV`);if(t.localSelection)return a(t.localSelection,`local`,`in ${_}`);if(e.defaultEnvironment)return a(e.defaultEnvironment,`default`,`as "defaultEnvironment"`);if(n.length===1)return{name:n[0],source:`sole`};throw n.length===0?new x(`no-selection`,`${i} has no environments defined. Run 'primitive env add <name>' or 'primitive init'.`,t.configPath):new x(`no-selection`,`No environment selected. Run 'primitive env use <name>', set "defaultEnvironment" in ${i}, or export PRIMITIVE_ENV. Available: ${r}`,t.configPath)}function N(e={}){let t=e.env??process.env,n=e.configPath??D({cwd:e.cwd,env:t});if(!n)throw new x(`missing-config`,b(e.cwd??process.cwd()));let r=O(n);E(r);let i=A(n),{name:a,source:o}=M(i,{explicitEnvName:e.explicitEnvName||null,envVarName:t.PRIMITIVE_ENV||null,localSelection:j(n),configPath:n}),s=i.environments[a];return{name:a,apiUrl:s.apiUrl,wsUrl:T(s.apiUrl),appId:s.appId,appName:s.appName,webUrl:s.webUrl,description:s.description,source:o,configPath:n,localStatePath:k(n),projectRoot:r}}var P=[`VITE_APP_ID`,`VITE_API_URL`,`VITE_WS_URL`,`VITE_APP_NAME`],F=`VITE_EXPECTED_PRIMITIVE_ENV`,I=new Map;function L(e,t){let n=process.env[e];n!==void 0&&n!==``&&I.get(e)!==n||(process.env[e]=t,I.set(e,t))}function R(e={}){return N({cwd:e.root,env:e.env,explicitEnvName:e.primitiveEnv??null})}function z(e,t,n){let r=e=>n.includes(e)?` (overridden)`:``,i=[`[primitive-env] Primitive environment: ${e.name} (selected: ${e.source})`,`[primitive-env] apiUrl: ${t.apiUrl}${r(`VITE_API_URL`)}`,`[primitive-env] wsUrl: ${t.wsUrl}${r(`VITE_WS_URL`)}`,`[primitive-env] appId: ${t.appId??`(unset)`}${r(`VITE_APP_ID`)}`,`[primitive-env] appName: ${t.appName??`(unset)`}${r(`VITE_APP_NAME`)}`,`[primitive-env] config: ${e.configPath}`];return n.length>0&&i.push(`[primitive-env] overridden by the environment: ${n.join(`, `)}`),i.join(`
|
|
69
|
+
`)}function B(e,t){let n=e?.envDir;return n===!1?null:typeof n==`string`&&n!==``?(0,a.resolve)(t,n):t}function V(e,t){let n=process.env[F];if(n!==void 0&&n!==``)return{value:n,where:`the process environment`};if(t===null)return null;for(let n of[`.env.${e}.local`,`.env.${e}`,`.env.local`,`.env`]){let e=K((0,a.join)(t,n))[F];if(e!==void 0)return{value:e,where:n}}return null}function H(e,t,n){return[`[primitive-env] Wrong pair: vite mode "${e}" is declared to run against Primitive environment "${t.value}", but "${n.name}" resolved.`,`[primitive-env] expected: ${t.value} (${F} in ${t.where})`,`[primitive-env] resolved: ${n.name} (selected: ${n.source})`,`[primitive-env] config: ${n.configPath}`,``,`Run the pair you meant — PRIMITIVE_ENV=${t.value} <command> --mode ${e}, or 'primitive env use ${t.value}' — or change/remove ${F} in ${t.where}.`,``,`A mode declares this when its .env.${e} carries values coupled to one backend, so continuing would run this environment's identity with another's configuration.`].join(`
|
|
70
|
+
`)}function U(e,t,n){let r=V(e,t);if(r&&r.value!==``&&r.value!==n.name)throw Error(H(e,r,n))}function W(e={}){let t=null,n=null,r,i=[],a=!1,o=null;return{name:`primitive-env`,enforce:`pre`,config(s,c){a=c?.command===`serve`,o=null;let l=s?.root??process.cwd(),u=c?.mode??`development`,d=G(u,l),f={};for(let e of P){let t=process.env[e],n=t!==void 0&&I.get(e)!==t?t:d[e];n!==void 0&&n!==``&&(f[e]=n)}let p;try{p=N({cwd:l,explicitEnvName:e.primitiveEnv??null})}catch(e){if(e instanceof x&&e.kind===`missing-config`&&f.VITE_APP_ID&&f.VITE_API_URL)return console.warn(`[primitive-env] No primitive/config.json found; using VITE_APP_ID / VITE_API_URL from the environment. Run 'primitive init' to make the project the source of truth.`),r=f.VITE_APP_NAME,{};throw e}if(!(f.VITE_APP_ID&&f.VITE_API_URL)){let e=B(s,l);U(u,e,p),o={root:l,mode:u,dir:e}}t=p,r=f.VITE_APP_NAME??p.appName;let m={VITE_APP_ID:p.appId,VITE_API_URL:p.apiUrl,VITE_WS_URL:p.wsUrl,VITE_APP_NAME:p.appName},h={"import.meta.env.VITE_PRIMITIVE_ENV":JSON.stringify(p.name)},g=[];for(let e of P){if(f[e]!==void 0){g.push(e);continue}let t=m[e];t!==void 0&&(h[`import.meta.env.${e}`]=JSON.stringify(t),L(e,t))}return L(`VITE_PRIMITIVE_ENV`,p.name),i=g,n={apiUrl:f.VITE_API_URL??p.apiUrl,wsUrl:f.VITE_WS_URL??p.wsUrl,appId:f.VITE_APP_ID??p.appId,appName:r},e.logResolved!==!1&&console.log(z(p,n,g)),g.length>0&&console.warn(`[primitive-env] Overridden by an explicit value in .env or the shell: ${g.join(`, `)}. Remove it to use primitive/config.json (deploys reject these outright).`),{define:h}},configResolved(e){if(!o||!t)return;let n=B(e,o.root),r=e?.mode??o.mode;n===o.dir&&r===o.mode||(U(r,n,t),o={root:o.root,mode:r,dir:n})},transformIndexHtml(){if(!a||!t||!n)return[];let e=`%c[primitive] env=${t.name} api=${n.apiUrl} app=${n.appId??`(unset)`} (${t.configPath})`+(i.length>0?` overridden: ${i.join(`, `)}`:``);return[{tag:`script`,injectTo:`head`,children:`console.info(${JSON.stringify(e)}, "color:#888");`}]},appName(){return r},resolved(){return t}}}function G(e,t){let n=[`.env`,`.env.local`,`.env.${e}`,`.env.${e}.local`],r={};for(let e of n)Object.assign(r,K((0,a.join)(t,e)));return r}function K(e){if(!(0,t.existsSync)(e))return{};let n={};for(let r of(0,t.readFileSync)(e,`utf-8`).split(/\r?\n/)){let e=r.trim();if(!e||e.startsWith(`#`))continue;let t=e.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!t)continue;let i=t[2].trim(),a=i[0],o=a===`"`||a===`'`||a==="`"?i.indexOf(a,1):-1;n[t[1]]=o===-1?i.replace(/\s+#.*$/,``).trim():i.slice(1,o)}return n}exports.PrimitiveEnvError=x,exports.primitiveDevTools=d,exports.primitiveEnv=W,exports.resolvePrimitiveEnv=R;
|
|
@@ -67,14 +67,17 @@ var h = "primitive", g = ".primitive", _ = "config.json", v = "local.json", y =
|
|
|
67
67
|
function S(e) {
|
|
68
68
|
return `${e} The Primitive configuration tree moved out of the hidden directory: the config is now ${y} and each environment's TOML is at primitive/<env>/, while .primitive/ keeps only machine-local state. Nothing is read from either tree until the project is migrated — follow ${x}.`;
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
function C(e) {
|
|
71
|
+
return `No ${y} found in ${e} or any parent directory. Primitive commands run inside a Primitive project: it is where the CLI reads the environment, the app that environment names, and the configuration tree from. Run 'primitive init' to create one.`;
|
|
72
|
+
}
|
|
73
|
+
var w = class extends Error {
|
|
71
74
|
kind;
|
|
72
75
|
path;
|
|
73
76
|
constructor(e, t, n) {
|
|
74
77
|
super(t), this.name = "PrimitiveEnvError", this.kind = e, this.path = n;
|
|
75
78
|
}
|
|
76
79
|
};
|
|
77
|
-
function
|
|
80
|
+
function T(e) {
|
|
78
81
|
if (typeof e != "string") return;
|
|
79
82
|
let t = e.trim();
|
|
80
83
|
if (!t) return;
|
|
@@ -86,89 +89,89 @@ function w(e) {
|
|
|
86
89
|
}
|
|
87
90
|
if (!(n.protocol !== "https:" && n.protocol !== "http:") && !(n.protocol === "http:" && n.hostname !== "localhost" && n.hostname !== "127.0.0.1") && !(n.username || n.password) && !(n.pathname !== "/" && n.pathname !== "") && !(n.search || n.hash)) return n.origin;
|
|
88
91
|
}
|
|
89
|
-
function
|
|
90
|
-
return `Environment "${e}" in ${t ? `${y} (${t})` : y} has no "appId". Every environment names exactly one app — add "appId": "<app-id>" to that environment in ${y}. Find the app id in the Primitive admin UI, with 'primitive apps list' run from
|
|
92
|
+
function E(e, t) {
|
|
93
|
+
return `Environment "${e}" in ${t ? `${y} (${t})` : y} has no "appId". Every environment names exactly one app — add "appId": "<app-id>" to that environment in ${y}. Find the app id in the Primitive admin UI, with 'primitive apps list' run from another Primitive project, or as the residual "currentAppId" in .primitive/credentials.json if this environment was ever pointed at an app by the retired per-machine app selection.`;
|
|
91
94
|
}
|
|
92
|
-
function
|
|
95
|
+
function D(e) {
|
|
93
96
|
if (typeof e == "string") return e.trim() || void 0;
|
|
94
97
|
}
|
|
95
|
-
function
|
|
98
|
+
function O(e) {
|
|
96
99
|
return e.startsWith("https://") ? "wss://" + e.slice(8) : e.startsWith("http://") ? "ws://" + e.slice(7) : e;
|
|
97
100
|
}
|
|
98
|
-
function
|
|
101
|
+
function k(t) {
|
|
99
102
|
let n = s(t, g, _);
|
|
100
|
-
if (e(n)) throw new
|
|
103
|
+
if (e(n)) throw new w("stale-layout", S(`${n} still exists.`), n);
|
|
101
104
|
let r = s(t, g, "sync");
|
|
102
|
-
if (e(r)) throw new
|
|
105
|
+
if (e(r)) throw new w("stale-layout", S(`${r} still exists.`), r);
|
|
103
106
|
}
|
|
104
|
-
function
|
|
107
|
+
function A(t = {}) {
|
|
105
108
|
let n = (t.env ?? process.env).PRIMITIVE_PROJECT_CONFIG;
|
|
106
109
|
if (n) {
|
|
107
110
|
let t = c(n);
|
|
108
|
-
if (a(o(t)) === ".primitive") throw new
|
|
109
|
-
return e(t) ? (
|
|
111
|
+
if (a(o(t)) === ".primitive") throw new w("stale-layout", S(`PRIMITIVE_PROJECT_CONFIG points at ${t}, inside a ${g}/ directory.`), t);
|
|
112
|
+
return e(t) ? (k(j(t)), t) : null;
|
|
110
113
|
}
|
|
111
114
|
let r = c(t.cwd ?? process.cwd());
|
|
112
115
|
for (;;) {
|
|
113
116
|
let t = s(r, h, _);
|
|
114
|
-
if (
|
|
117
|
+
if (k(r), e(t)) return t;
|
|
115
118
|
let n = o(r);
|
|
116
119
|
if (n === r) return null;
|
|
117
120
|
r = n;
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
|
-
function
|
|
123
|
+
function j(e) {
|
|
121
124
|
let t = o(e);
|
|
122
125
|
return a(t) === "primitive" ? o(t) : t;
|
|
123
126
|
}
|
|
124
|
-
function
|
|
125
|
-
return s(
|
|
127
|
+
function M(e) {
|
|
128
|
+
return s(j(e), g, v);
|
|
126
129
|
}
|
|
127
|
-
function
|
|
128
|
-
if (!e(n)) throw new
|
|
130
|
+
function N(n) {
|
|
131
|
+
if (!e(n)) throw new w("missing-config", C(o(n)), n);
|
|
129
132
|
let r;
|
|
130
133
|
try {
|
|
131
134
|
r = t(n, "utf-8");
|
|
132
135
|
} catch (e) {
|
|
133
|
-
throw new
|
|
136
|
+
throw new w("malformed-config", `Failed to read ${y} (${n}): ${e.message}`, n);
|
|
134
137
|
}
|
|
135
138
|
let i;
|
|
136
139
|
try {
|
|
137
140
|
i = JSON.parse(r);
|
|
138
141
|
} catch (e) {
|
|
139
|
-
throw new
|
|
142
|
+
throw new w("malformed-config", `Failed to parse ${y} (${n}): ${e.message}`, n);
|
|
140
143
|
}
|
|
141
|
-
if (!i || typeof i != "object" || Array.isArray(i)) throw new
|
|
144
|
+
if (!i || typeof i != "object" || Array.isArray(i)) throw new w("malformed-config", `${y} (${n}) must contain a JSON object at the top level.`, n);
|
|
142
145
|
let a = i;
|
|
143
|
-
if (typeof a.version != "number" || !Number.isInteger(a.version)) throw new
|
|
144
|
-
if (a.version !== 1) throw new
|
|
145
|
-
if (!a.environments || typeof a.environments != "object" || Array.isArray(a.environments)) throw new
|
|
146
|
-
let
|
|
146
|
+
if (typeof a.version != "number" || !Number.isInteger(a.version)) throw new w("malformed-config", `${y} (${n}) is missing required integer field "version".`, n);
|
|
147
|
+
if (a.version !== 1) throw new w("unsupported-version", `${y} (${n}) has version ${a.version}, but this tool understands version 1.`, n);
|
|
148
|
+
if (!a.environments || typeof a.environments != "object" || Array.isArray(a.environments)) throw new w("malformed-config", `${y} (${n}) is missing required "environments" object.`, n);
|
|
149
|
+
let s = {};
|
|
147
150
|
for (let [e, t] of Object.entries(a.environments)) {
|
|
148
|
-
if (!t || typeof t != "object" || Array.isArray(t)) throw new
|
|
151
|
+
if (!t || typeof t != "object" || Array.isArray(t)) throw new w("malformed-config", `Environment "${e}" must be an object in ${y} (${n}).`, n);
|
|
149
152
|
let r = t;
|
|
150
|
-
if (typeof r.apiUrl != "string" || !r.apiUrl) throw new
|
|
151
|
-
let i =
|
|
152
|
-
if (!i) throw new
|
|
153
|
-
|
|
153
|
+
if (typeof r.apiUrl != "string" || !r.apiUrl) throw new w("malformed-config", `Environment "${e}" must have a non-empty "apiUrl" string in ${y} (${n}).`, n);
|
|
154
|
+
let i = D(r.appId);
|
|
155
|
+
if (!i) throw new w("missing-app-id", E(e, n), n);
|
|
156
|
+
s[e] = {
|
|
154
157
|
apiUrl: r.apiUrl.replace(/\/$/, ""),
|
|
155
158
|
appId: i,
|
|
156
159
|
appName: typeof r.appName == "string" ? r.appName : void 0,
|
|
157
|
-
webUrl:
|
|
160
|
+
webUrl: T(r.webUrl),
|
|
158
161
|
description: typeof r.description == "string" ? r.description : void 0
|
|
159
162
|
};
|
|
160
163
|
}
|
|
161
164
|
return {
|
|
162
165
|
version: a.version,
|
|
163
166
|
defaultEnvironment: typeof a.defaultEnvironment == "string" && a.defaultEnvironment ? a.defaultEnvironment : void 0,
|
|
164
|
-
environments:
|
|
167
|
+
environments: s
|
|
165
168
|
};
|
|
166
169
|
}
|
|
167
|
-
function
|
|
168
|
-
let r =
|
|
170
|
+
function P(n) {
|
|
171
|
+
let r = M(n);
|
|
169
172
|
if (!e(r)) return null;
|
|
170
173
|
let i = (e) => {
|
|
171
|
-
throw new
|
|
174
|
+
throw new w("corrupt-local-state", `${b} (${r}) is unreadable: ${e}. Delete the file or re-run 'primitive env use <name>'.`, r);
|
|
172
175
|
}, a;
|
|
173
176
|
try {
|
|
174
177
|
a = JSON.parse(t(r, "utf-8"));
|
|
@@ -179,9 +182,9 @@ function N(n) {
|
|
|
179
182
|
let o = a.selectedEnvironment;
|
|
180
183
|
return o == null || o === "" ? null : typeof o == "string" ? o : i("\"selectedEnvironment\" must be a string");
|
|
181
184
|
}
|
|
182
|
-
function
|
|
185
|
+
function F(e, t) {
|
|
183
186
|
let n = Object.keys(e.environments), r = n.join(", ") || "(none)", i = t.configPath ? `${y} (${t.configPath})` : y, a = (n, a, o) => {
|
|
184
|
-
if (!e.environments[n]) throw new
|
|
187
|
+
if (!e.environments[n]) throw new w("unknown-environment", `Environment "${n}" is not defined in ${i} (selected ${o}). Available: ${r}`, t.configPath);
|
|
185
188
|
return {
|
|
186
189
|
name: n,
|
|
187
190
|
source: a
|
|
@@ -195,56 +198,56 @@ function P(e, t) {
|
|
|
195
198
|
name: n[0],
|
|
196
199
|
source: "sole"
|
|
197
200
|
};
|
|
198
|
-
throw n.length === 0 ? new
|
|
201
|
+
throw n.length === 0 ? new w("no-selection", `${i} has no environments defined. Run 'primitive env add <name>' or 'primitive init'.`, t.configPath) : new w("no-selection", `No environment selected. Run 'primitive env use <name>', set "defaultEnvironment" in ${i}, or export PRIMITIVE_ENV. Available: ${r}`, t.configPath);
|
|
199
202
|
}
|
|
200
|
-
function
|
|
201
|
-
let t = e.env ?? process.env, n = e.configPath ??
|
|
203
|
+
function I(e = {}) {
|
|
204
|
+
let t = e.env ?? process.env, n = e.configPath ?? A({
|
|
202
205
|
cwd: e.cwd,
|
|
203
206
|
env: t
|
|
204
207
|
});
|
|
205
|
-
if (!n) throw new
|
|
206
|
-
let r =
|
|
207
|
-
|
|
208
|
-
let i =
|
|
208
|
+
if (!n) throw new w("missing-config", C(e.cwd ?? process.cwd()));
|
|
209
|
+
let r = j(n);
|
|
210
|
+
k(r);
|
|
211
|
+
let i = N(n), { name: a, source: o } = F(i, {
|
|
209
212
|
explicitEnvName: e.explicitEnvName || null,
|
|
210
213
|
envVarName: t.PRIMITIVE_ENV || null,
|
|
211
|
-
localSelection:
|
|
214
|
+
localSelection: P(n),
|
|
212
215
|
configPath: n
|
|
213
216
|
}), s = i.environments[a];
|
|
214
217
|
return {
|
|
215
218
|
name: a,
|
|
216
219
|
apiUrl: s.apiUrl,
|
|
217
|
-
wsUrl:
|
|
220
|
+
wsUrl: O(s.apiUrl),
|
|
218
221
|
appId: s.appId,
|
|
219
222
|
appName: s.appName,
|
|
220
223
|
webUrl: s.webUrl,
|
|
221
224
|
description: s.description,
|
|
222
225
|
source: o,
|
|
223
226
|
configPath: n,
|
|
224
|
-
localStatePath:
|
|
227
|
+
localStatePath: M(n),
|
|
225
228
|
projectRoot: r
|
|
226
229
|
};
|
|
227
230
|
}
|
|
228
231
|
//#endregion
|
|
229
232
|
//#region src/dev-tools/vite-plugin/primitive-env.ts
|
|
230
|
-
var
|
|
233
|
+
var L = [
|
|
231
234
|
"VITE_APP_ID",
|
|
232
235
|
"VITE_API_URL",
|
|
233
236
|
"VITE_WS_URL",
|
|
234
237
|
"VITE_APP_NAME"
|
|
235
|
-
],
|
|
236
|
-
function
|
|
238
|
+
], R = "VITE_EXPECTED_PRIMITIVE_ENV", z = /* @__PURE__ */ new Map();
|
|
239
|
+
function B(e, t) {
|
|
237
240
|
let n = process.env[e];
|
|
238
|
-
n !== void 0 && n !== "" &&
|
|
241
|
+
n !== void 0 && n !== "" && z.get(e) !== n || (process.env[e] = t, z.set(e, t));
|
|
239
242
|
}
|
|
240
|
-
function
|
|
241
|
-
return
|
|
243
|
+
function V(e = {}) {
|
|
244
|
+
return I({
|
|
242
245
|
cwd: e.root,
|
|
243
246
|
env: e.env,
|
|
244
247
|
explicitEnvName: e.primitiveEnv ?? null
|
|
245
248
|
});
|
|
246
249
|
}
|
|
247
|
-
function
|
|
250
|
+
function H(e, t, n) {
|
|
248
251
|
let r = (e) => n.includes(e) ? " (overridden)" : "", i = [
|
|
249
252
|
`[primitive-env] Primitive environment: ${e.name} (selected: ${e.source})`,
|
|
250
253
|
`[primitive-env] apiUrl: ${t.apiUrl}${r("VITE_API_URL")}`,
|
|
@@ -255,12 +258,12 @@ function V(e, t, n) {
|
|
|
255
258
|
];
|
|
256
259
|
return n.length > 0 && i.push(`[primitive-env] overridden by the environment: ${n.join(", ")}`), i.join("\n");
|
|
257
260
|
}
|
|
258
|
-
function
|
|
261
|
+
function U(e, t) {
|
|
259
262
|
let n = e?.envDir;
|
|
260
263
|
return n === !1 ? null : typeof n == "string" && n !== "" ? c(t, n) : t;
|
|
261
264
|
}
|
|
262
|
-
function
|
|
263
|
-
let n = process.env[
|
|
265
|
+
function W(e, t) {
|
|
266
|
+
let n = process.env[R];
|
|
264
267
|
if (n !== void 0 && n !== "") return {
|
|
265
268
|
value: n,
|
|
266
269
|
where: "the process environment"
|
|
@@ -272,7 +275,7 @@ function U(e, t) {
|
|
|
272
275
|
".env.local",
|
|
273
276
|
".env"
|
|
274
277
|
]) {
|
|
275
|
-
let e =
|
|
278
|
+
let e = Y(s(t, n))[R];
|
|
276
279
|
if (e !== void 0) return {
|
|
277
280
|
value: e,
|
|
278
281
|
where: n
|
|
@@ -280,47 +283,47 @@ function U(e, t) {
|
|
|
280
283
|
}
|
|
281
284
|
return null;
|
|
282
285
|
}
|
|
283
|
-
function
|
|
286
|
+
function G(e, t, n) {
|
|
284
287
|
return [
|
|
285
288
|
`[primitive-env] Wrong pair: vite mode "${e}" is declared to run against Primitive environment "${t.value}", but "${n.name}" resolved.`,
|
|
286
|
-
`[primitive-env] expected: ${t.value} (${
|
|
289
|
+
`[primitive-env] expected: ${t.value} (${R} in ${t.where})`,
|
|
287
290
|
`[primitive-env] resolved: ${n.name} (selected: ${n.source})`,
|
|
288
291
|
`[primitive-env] config: ${n.configPath}`,
|
|
289
292
|
"",
|
|
290
|
-
`Run the pair you meant — PRIMITIVE_ENV=${t.value} <command> --mode ${e}, or 'primitive env use ${t.value}' — or change/remove ${
|
|
293
|
+
`Run the pair you meant — PRIMITIVE_ENV=${t.value} <command> --mode ${e}, or 'primitive env use ${t.value}' — or change/remove ${R} in ${t.where}.`,
|
|
291
294
|
"",
|
|
292
295
|
`A mode declares this when its .env.${e} carries values coupled to one backend, so continuing would run this environment's identity with another's configuration.`
|
|
293
296
|
].join("\n");
|
|
294
297
|
}
|
|
295
|
-
function
|
|
296
|
-
let r =
|
|
297
|
-
if (r && r.value !== "" && r.value !== n.name) throw Error(
|
|
298
|
+
function K(e, t, n) {
|
|
299
|
+
let r = W(e, t);
|
|
300
|
+
if (r && r.value !== "" && r.value !== n.name) throw Error(G(e, r, n));
|
|
298
301
|
}
|
|
299
|
-
function
|
|
302
|
+
function q(e = {}) {
|
|
300
303
|
let t = null, n = null, r, i = [], a = !1, o = null;
|
|
301
304
|
return {
|
|
302
305
|
name: "primitive-env",
|
|
303
306
|
enforce: "pre",
|
|
304
307
|
config(s, c) {
|
|
305
308
|
a = c?.command === "serve", o = null;
|
|
306
|
-
let l = s?.root ?? process.cwd(), u = c?.mode ?? "development", d =
|
|
307
|
-
for (let e of
|
|
308
|
-
let t = process.env[e], n = t !== void 0 &&
|
|
309
|
+
let l = s?.root ?? process.cwd(), u = c?.mode ?? "development", d = J(u, l), f = {};
|
|
310
|
+
for (let e of L) {
|
|
311
|
+
let t = process.env[e], n = t !== void 0 && z.get(e) !== t ? t : d[e];
|
|
309
312
|
n !== void 0 && n !== "" && (f[e] = n);
|
|
310
313
|
}
|
|
311
314
|
let p;
|
|
312
315
|
try {
|
|
313
|
-
p =
|
|
316
|
+
p = I({
|
|
314
317
|
cwd: l,
|
|
315
318
|
explicitEnvName: e.primitiveEnv ?? null
|
|
316
319
|
});
|
|
317
320
|
} catch (e) {
|
|
318
|
-
if (e instanceof
|
|
321
|
+
if (e instanceof w && e.kind === "missing-config" && f.VITE_APP_ID && f.VITE_API_URL) return console.warn("[primitive-env] No primitive/config.json found; using VITE_APP_ID / VITE_API_URL from the environment. Run 'primitive init' to make the project the source of truth."), r = f.VITE_APP_NAME, {};
|
|
319
322
|
throw e;
|
|
320
323
|
}
|
|
321
324
|
if (!(f.VITE_APP_ID && f.VITE_API_URL)) {
|
|
322
|
-
let e =
|
|
323
|
-
|
|
325
|
+
let e = U(s, l);
|
|
326
|
+
K(u, e, p), o = {
|
|
324
327
|
root: l,
|
|
325
328
|
mode: u,
|
|
326
329
|
dir: e
|
|
@@ -333,25 +336,25 @@ function K(e = {}) {
|
|
|
333
336
|
VITE_WS_URL: p.wsUrl,
|
|
334
337
|
VITE_APP_NAME: p.appName
|
|
335
338
|
}, h = { "import.meta.env.VITE_PRIMITIVE_ENV": JSON.stringify(p.name) }, g = [];
|
|
336
|
-
for (let e of
|
|
339
|
+
for (let e of L) {
|
|
337
340
|
if (f[e] !== void 0) {
|
|
338
341
|
g.push(e);
|
|
339
342
|
continue;
|
|
340
343
|
}
|
|
341
344
|
let t = m[e];
|
|
342
|
-
t !== void 0 && (h[`import.meta.env.${e}`] = JSON.stringify(t),
|
|
345
|
+
t !== void 0 && (h[`import.meta.env.${e}`] = JSON.stringify(t), B(e, t));
|
|
343
346
|
}
|
|
344
|
-
return
|
|
347
|
+
return B("VITE_PRIMITIVE_ENV", p.name), i = g, n = {
|
|
345
348
|
apiUrl: f.VITE_API_URL ?? p.apiUrl,
|
|
346
349
|
wsUrl: f.VITE_WS_URL ?? p.wsUrl,
|
|
347
350
|
appId: f.VITE_APP_ID ?? p.appId,
|
|
348
351
|
appName: r
|
|
349
|
-
}, e.logResolved !== !1 && console.log(
|
|
352
|
+
}, e.logResolved !== !1 && console.log(H(p, n, g)), g.length > 0 && console.warn(`[primitive-env] Overridden by an explicit value in .env or the shell: ${g.join(", ")}. Remove it to use primitive/config.json (deploys reject these outright).`), { define: h };
|
|
350
353
|
},
|
|
351
354
|
configResolved(e) {
|
|
352
355
|
if (!o || !t) return;
|
|
353
|
-
let n =
|
|
354
|
-
n === o.dir && r === o.mode || (
|
|
356
|
+
let n = U(e, o.root), r = e?.mode ?? o.mode;
|
|
357
|
+
n === o.dir && r === o.mode || (K(r, n, t), o = {
|
|
355
358
|
root: o.root,
|
|
356
359
|
mode: r,
|
|
357
360
|
dir: n
|
|
@@ -374,17 +377,17 @@ function K(e = {}) {
|
|
|
374
377
|
}
|
|
375
378
|
};
|
|
376
379
|
}
|
|
377
|
-
function
|
|
380
|
+
function J(e, t) {
|
|
378
381
|
let n = [
|
|
379
382
|
".env",
|
|
380
383
|
".env.local",
|
|
381
384
|
`.env.${e}`,
|
|
382
385
|
`.env.${e}.local`
|
|
383
386
|
], r = {};
|
|
384
|
-
for (let e of n) Object.assign(r,
|
|
387
|
+
for (let e of n) Object.assign(r, Y(s(t, e)));
|
|
385
388
|
return r;
|
|
386
389
|
}
|
|
387
|
-
function
|
|
390
|
+
function Y(n) {
|
|
388
391
|
if (!e(n)) return {};
|
|
389
392
|
let r = {};
|
|
390
393
|
for (let e of t(n, "utf-8").split(/\r?\n/)) {
|
|
@@ -398,4 +401,4 @@ function J(n) {
|
|
|
398
401
|
return r;
|
|
399
402
|
}
|
|
400
403
|
//#endregion
|
|
401
|
-
export {
|
|
404
|
+
export { w as PrimitiveEnvError, m as primitiveDevTools, q as primitiveEnv, V as resolvePrimitiveEnv };
|