@coreframe/scripts 0.1.45 → 0.1.46
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/assets/workflows.d.ts +12 -2
- package/dist/assets/workflows.js +1 -1
- package/dist/assets.d.ts +2 -2
- package/dist/assets.js +1 -1
- package/dist/coreframe.js +1 -1
- package/dist/dev-timing.d.ts +25 -0
- package/dist/dev-timing.js +1 -0
- package/dist/dev.js +1 -1
- package/dist/i18n/catalogs.d.ts +2 -3
- package/dist/i18n/catalogs.js +1 -1
- package/dist/i18n/contracts.d.ts +0 -1
- package/dist/i18n/storage.js +1 -1
- package/dist/i18n/workflows.d.ts +9 -2
- package/dist/i18n/workflows.js +1 -1
- package/dist/managed-dev.d.ts +2 -0
- package/dist/managed-dev.js +5 -5
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssetBuildResult, AssetPublishResult, AssetStatus } from "./contracts.js";
|
|
1
|
+
import { AssetBuildResult, AssetProblem, AssetPublishResult, AssetStatus } from "./contracts.js";
|
|
2
2
|
import { AssetsConfig } from "../config.js";
|
|
3
3
|
import { AssetObjectStore } from "./storage.js";
|
|
4
4
|
|
|
@@ -26,9 +26,18 @@ type CheckAssetsOptions = AssetWorkflowOptions & {
|
|
|
26
26
|
fix?: boolean;
|
|
27
27
|
pack?: string;
|
|
28
28
|
};
|
|
29
|
+
type CheckAssetManifestsOptions = AssetWorkflowOptions & {
|
|
30
|
+
pack?: string;
|
|
31
|
+
};
|
|
29
32
|
type PublishAssetsOptions = AssetWorkflowOptions & {
|
|
30
33
|
pack?: string;
|
|
31
34
|
};
|
|
35
|
+
type AssetManifestStatus = {
|
|
36
|
+
ok: boolean;
|
|
37
|
+
problems: AssetProblem[];
|
|
38
|
+
requiresFullBuild: boolean;
|
|
39
|
+
staleAssetIds: string[];
|
|
40
|
+
};
|
|
32
41
|
declare function addAsset({
|
|
33
42
|
alt,
|
|
34
43
|
cacheDir,
|
|
@@ -51,9 +60,10 @@ declare function buildAssets({
|
|
|
51
60
|
store,
|
|
52
61
|
updateManifest
|
|
53
62
|
}?: BuildAssetsOptions): Promise<AssetBuildResult>;
|
|
63
|
+
declare function checkAssetManifests(options?: CheckAssetManifestsOptions): Promise<AssetManifestStatus>;
|
|
54
64
|
declare function checkAssets(options?: CheckAssetsOptions): Promise<AssetStatus>;
|
|
55
65
|
declare function publishAssets(options?: PublishAssetsOptions): Promise<AssetPublishResult>;
|
|
56
66
|
declare function materializeAsset(assetId: string, options?: BuildAssetsOptions): Promise<AssetBuildResult>;
|
|
57
67
|
declare function printAssetResult(result: unknown, json?: boolean): void;
|
|
58
68
|
//#endregion
|
|
59
|
-
export { AddAssetOptions, AssetWorkflowOptions, BuildAssetsOptions, CheckAssetsOptions, PublishAssetsOptions, addAsset, buildAssets, checkAssets, materializeAsset, printAssetResult, publishAssets };
|
|
69
|
+
export { AddAssetOptions, AssetManifestStatus, AssetWorkflowOptions, BuildAssetsOptions, CheckAssetManifestsOptions, CheckAssetsOptions, PublishAssetsOptions, addAsset, buildAssets, checkAssetManifests, checkAssets, materializeAsset, printAssetResult, publishAssets };
|
package/dist/assets/workflows.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./contracts.js";import{assertAssetId as e,assertAssetPackName as t,assetCatalogEntries as n,assetCatalogPackNames as r,assetIdPattern as i,assetManifestPath as a,catalogPath as o,findAssetReferences as s,findCatalogAsset as c,formatAssetProblems as l,isAssetVariantPath as u,listAssetManifestPacks as d,manifestEntryMatchesCatalog as f,manifestEntryOutputs as p,readAssetCatalog as m,readAssetManifest as h,removeAssetManifest as g,resolveAssetVariantFile as _,resolveAssetsConfig as v,setCatalogAsset as y,validateSource as b,writeCatalog as x,writeManifest as S}from"./project.js";import{assetCacheRoot as C,assetSourceKey as w,cacheAssetSourceFile as T,createB2AssetStore as E,materializeAssetSource as D,sha256File as O}from"./storage.js";import{assertVariantWidths as k,assetVariantWidths as A,buildAssetVariants as j,mediaTypeFor as M,readImageDimensions as N,variantWidthsProblem as P}from"./images.js";import{assetKindFor as F,buildPassthroughAsset as I,inspectAudio as L,inspectLottie as R,inspectSvg as z,inspectVideo as B,mediaTypeForAsset as V}from"./media.js";import{mkdir as H,stat as U,writeFile as W}from"node:fs/promises";import{basename as G,dirname as K,join as q,relative as J,resolve as Y,sep as X}from"node:path";const Z=q(`.coreframe/assets`,`asset-publish-report.json`);async function ee({alt:n,cacheDir:r,config:i,cwd:a=process.cwd(),env:o=process.env,file:s,id:c,pack:l,store:u,variantWidths:d}){e(c),l!==void 0&&t(l);let f=Y(a,s),p=F(f),h=n?.trim();if((p===`image`||p===`svg`)&&!h)throw Error(`Raster images and SVG assets require non-empty alt text.`);if(p!==`image`&&d)throw Error(`Asset kind "${p}" does not support responsive variant widths.`);await ne(p,f,d);let g=await m(a,{allowMissing:!0,migrate:!0});if(g.problems.length>0)return{ok:!1,assets:[],fetched:[],problems:g.problems};let _=await v(a,i),b=u??E({config:_,env:o}),S=await O(f),D={digest:S,filename:G(s),mediaType:p===`image`?M(s):V(s,p),size:(await U(f)).size},k=r??C(o),A=await T({cacheRoot:k,digest:S,env:o,source:f}),j=w(S);if(!await b.has(_.sourceBucket,j)&&(await b.upload(_.sourceBucket,j,A,D.mediaType),!await b.has(_.sourceBucket,j)))throw Error(`Backblaze B2 did not confirm source upload ${j}.`);return y(g.catalog,c,te({alt:h,kind:p,source:D,variantWidths:d}),l),await x(a,g.catalog),Q({cacheDir:k,config:_,cwd:a,env:o,id:g.migrated?void 0:c,pack:g.migrated?void 0:l,store:b})}function te({alt:e,kind:t,source:n,variantWidths:r}){return t===`image`?{kind:t,source:n,alt:e,...r?{variantWidths:r}:{}}:t===`svg`?{kind:t,source:n,alt:e}:{kind:t,source:n}}async function ne(e,t,n){if(e===`image`){k(n,(await N(t)).width),M(t);return}if(e===`svg`){await z(t);return}if(e===`audio`){await L(t);return}if(e===`video`){await B(t);return}await R(t)}async function Q({cacheDir:e,config:i,cwd:a=process.cwd(),env:s=process.env,id:l,pack:u,store:f,updateManifest:_=!0}={}){u!==void 0&&t(u);let y=await m(a,{migrate:!0}),x=[...y.problems],T=[],O=[];if(x.length>0)return{ok:!1,assets:T,fetched:O,problems:x};y.migrated&&(l=void 0,u=void 0);let k=n(y.catalog),A=l?c(y.catalog,l):void 0;if(l&&!A)return x.push({code:`REFERENCE_MISSING`,message:`Asset "${l}" is not present in ${o}.`,assetId:l,fix:`Run: coreframe assets add <file> --id ${l}`}),{ok:!1,assets:T,fetched:O,problems:x};if(l&&u!==void 0&&A?.pack!==u)return x.push({code:`REFERENCE_MISSING`,message:`Asset "${l}" is not present in asset pack "${u}".`,assetId:l,fix:`Build the asset without --pack or use its owning pack.`}),{ok:!1,assets:T,fetched:O,problems:x};let j=l?A?.pack:u;if(!l&&u!==void 0&&!y.catalog.packs?.[u])return x.push({code:`REFERENCE_MISSING`,message:`Asset pack "${u}" is not present in ${o}.`,fix:`Add an asset with --pack ${u}.`}),{ok:!1,assets:T,fetched:O,problems:x};let M=k.filter(e=>(l===void 0||e.assetId===l)&&(j===void 0?u===void 0||e.pack===void 0:e.pack===j)),N=l!==void 0||u!==void 0?[j]:[void 0,...r(y.catalog)],P=await v(a,i),F=f??E({config:P,env:s}),I=e??C(s),L=new Map;for(let e of N)if(l&&_){let t=await h(a,{allowMissing:!0,pack:e});if(t.problems.length>0)return{ok:!1,assets:T,fetched:O,problems:t.problems};L.set(e,t.manifest)}else L.set(e,re(e));for(let{assetId:e,entry:t,pack:n}of M){let r=b(e,t);if(r){x.push(r);continue}let i;try{i=await D({bucket:P.sourceBucket,cacheRoot:I,digest:t.source.digest,env:s,store:F})}catch(t){x.push({code:`SOURCE_UNAVAILABLE`,message:`Asset "${e}" source could not be materialized: ${t.message}`,assetId:e,fix:`Check the B2 asset configuration and credential profile "${P.credentialProfile}".`});continue}i.fetched&&O.push(w(t.source.digest));try{let r=await ie({assetId:e,config:P,cwd:a,entry:t,sourcePath:i.path});L.get(n).assets[e]=r,T.push({assetId:e,outputs:p(r)})}catch(n){x.push({code:`INVALID_MEDIA`,message:`Asset "${e}" could not be built: ${n.message}`,assetId:e,file:o,fix:`Replace the source with a supported ${t.kind} file, then run: coreframe assets build --id ${e}`})}}if(_&&x.length===0){for(let[e,t]of L)await S(a,t,e);if(l===void 0&&u===void 0){let e=new Set(r(y.catalog));for(let t of await d(a))e.has(t)||await g(a,t)}}return{ok:x.length===0,assets:T,fetched:O,problems:x}}function re(e){return{schemaVersion:2,...e===void 0?{}:{pack:e},assets:{}}}async function ie({assetId:e,config:t,cwd:n,entry:r,sourcePath:i}){if(r.kind===`image`){let a=await N(i),o=P(e,r,a.width);if(o)throw Error(o.message);let s=await j({assetId:e,config:t,cwd:n,entry:r,sourcePath:i,sourceDimensions:a});return{kind:`image`,sourceDigest:r.source.digest,alt:r.alt,...a,variants:s}}let a=await I({assetId:e,cwd:n,format:r.kind===`svg`?`svg`:r.kind===`audio`?`mp3`:r.kind===`video`?`mp4`:`json`,mediaType:r.source.mediaType,projectId:t.projectId,sourceDigest:r.source.digest,sourcePath:i});return r.kind===`svg`?{kind:`svg`,sourceDigest:r.source.digest,alt:r.alt,...await z(i),file:a}:r.kind===`audio`?{kind:`audio`,sourceDigest:r.source.digest,...await L(i),file:a}:r.kind===`video`?{kind:`video`,sourceDigest:r.source.digest,...await B(i),file:a}:{kind:`lottie`,sourceDigest:r.source.digest,...await R(i),file:a}}async function $(e={}){let{cwd:l=process.cwd(),fix:g=!1,pack:y}=e;if(y!==void 0&&t(y),g){let t=await Q(e);if(!t.ok)return{ok:!1,assets:[],problems:t.problems}}let x=await m(l),S=[...x.problems],C=[];if(S.some(e=>e.code===`SCHEMA_MIGRATION_REQUIRED`))return{ok:!1,assets:C,problems:S};if(y!==void 0&&!x.catalog.packs?.[y])return S.push({code:`REFERENCE_MISSING`,message:`Asset pack "${y}" is not present in ${o}.`,fix:`Add an asset with --pack ${y}.`}),{ok:!1,assets:C,problems:S};let w=y===void 0?[void 0,...r(x.catalog)]:[y],T=new Map;for(let e of w){let t=await h(l,{pack:e});S.push(...t.problems),T.set(e,t.manifest)}if(y===void 0){let e=new Set(r(x.catalog));for(let t of await d(l))e.has(t)||S.push({code:`MANIFEST_STALE`,message:`Generated asset pack manifest "${t}" is not present in the catalog.`,file:a(t),fix:`Run: coreframe assets build`})}let E=await s(l),D=`projects/${(await v(l,e.config)).projectId}/assets`,k=n(x.catalog).filter(e=>y===void 0||e.pack===y);for(let{assetId:e,entry:t,pack:n}of k){let r=a(n);i.test(e)||S.push({code:`INVALID_ASSET_ID`,message:`Asset ID "${e}" must use lowercase path segments.`,assetId:e,file:o}),(t.kind===`image`||t.kind===`svg`)&&!t.alt.trim()&&S.push({code:`INVALID_ALT`,message:`Asset "${e}" is missing alt text.`,assetId:e,file:o});let s=b(e,t);s&&S.push(s);let c=T.get(n)?.assets[e];if(!c||!f(c,t)){S.push({code:`MANIFEST_STALE`,message:`Asset "${e}" is missing from the generated manifest or does not match its catalog entry.`,assetId:e,file:r,fix:`Run: coreframe assets build --id ${e}`});continue}let d=await Promise.all(p(c).map(async t=>{let n=u(t.path,D),r=!1;if(n)try{let e=_(l,t.path);r=(await U(e)).size===t.size&&await O(e)===t.hash}catch{r=!1}return n||S.push({code:`INVALID_VARIANT_PATH`,message:`Asset "${e}" has an invalid generated output path.`,assetId:e,file:t.path,fix:`Run: coreframe assets build --id ${e}`}),{...t,exists:r}})),m=d.every(e=>e.exists);if(t.kind===`image`&&c.kind===`image`){let n=P(e,t,c.width);if(n)S.push(n);else{let e=A(t,c.width),n=c.variants.map(e=>e.width);m=m&&e.length===n.length&&e.every((e,t)=>e===n[t])}}m||S.push({code:`GENERATED_ASSET_MISSING`,message:`Asset "${e}" is missing its expected generated output.`,assetId:e,fix:`Run: coreframe assets build --id ${e}`}),C.push({assetId:e,source:t.source,outputs:d})}for(let[e,t]of T){let n=e===void 0?x.catalog.assets:x.catalog.packs?.[e]?.assets;for(let r of Object.keys(t.assets))n?.[r]||S.push({code:`MANIFEST_STALE`,message:`Generated manifest asset "${r}" is not present in its catalog collection.`,assetId:r,file:a(e),fix:`Run: coreframe assets build`})}for(let e of E){let t=c(x.catalog,e.assetId);t?t.entry.kind!==`image`&&t.entry.kind!==`svg`&&S.push({code:`INVALID_REFERENCE`,message:`Markdown image reference "${e.assetId}" cannot use asset kind "${t.entry.kind}".`,assetId:e.assetId,file:e.file}):S.push({code:`INVALID_REFERENCE`,message:`Asset reference "${e.assetId}" is not present in ${o}.`,assetId:e.assetId,file:e.file,fix:`Run: coreframe assets add <file> --id ${e.assetId}`})}return{ok:S.length===0,assets:C,problems:S}}async function ae(e={}){let{cwd:t=process.cwd(),env:n=process.env,pack:i}=e,a=[...(await $(e)).problems],o=[],s=[],c=Y(t,Z);if(a.length===0){let a=await v(t,e.config),c=e.store??E({config:a,env:n}),{catalog:l}=await m(t),u=i===void 0?[void 0,...r(l)]:[i];for(let e of u){let{manifest:n}=await h(t,{pack:e});for(let[e,r]of Object.entries(n.assets))for(let n of p(r)){let r=_(t,n.path),i={assetId:e,source:J(t,r).split(X).join(`/`),target:`${a.publicBucket}/${n.path}`,size:n.size};if(await c.has(a.publicBucket,n.path)){s.push(i);continue}await c.upload(a.publicBucket,n.path,r,n.mediaType),o.push(i)}}}let l={ok:a.length===0,uploaded:o,skipped:s,reportPath:c,problems:a};return await H(K(c),{recursive:!0}),await W(c,`${JSON.stringify(l,null,2)}\n`),l}async function oe(e,t={}){return Q({...t,id:e})}function se(e,t=!1){if(t){console.log(JSON.stringify(e,null,2));return}let n=e;n.problems?.length&&console.error(l(n.problems)),console.log(n.ok===!1?`Asset workflow has problems.`:`Asset workflow complete.`)}export{ee as addAsset,Q as buildAssets,$ as checkAssets,oe as materializeAsset,se as printAssetResult,ae as publishAssets};
|
|
1
|
+
import"./contracts.js";import{assertAssetId as e,assertAssetPackName as t,assetCatalogEntries as n,assetCatalogPackNames as r,assetIdPattern as i,assetManifestPath as a,catalogPath as o,findAssetReferences as s,findCatalogAsset as c,formatAssetProblems as l,isAssetVariantPath as u,listAssetManifestPacks as d,manifestEntryMatchesCatalog as f,manifestEntryOutputs as p,readAssetCatalog as m,readAssetManifest as h,removeAssetManifest as g,resolveAssetVariantFile as _,resolveAssetsConfig as v,setCatalogAsset as y,validateSource as b,writeCatalog as x,writeManifest as S}from"./project.js";import{assetCacheRoot as C,assetSourceKey as w,cacheAssetSourceFile as T,createB2AssetStore as E,materializeAssetSource as D,sha256File as O}from"./storage.js";import{assertVariantWidths as k,assetVariantWidths as A,buildAssetVariants as j,mediaTypeFor as M,readImageDimensions as N,variantWidthsProblem as P}from"./images.js";import{assetKindFor as F,buildPassthroughAsset as I,inspectAudio as L,inspectLottie as R,inspectSvg as z,inspectVideo as B,mediaTypeForAsset as V}from"./media.js";import{mkdir as H,stat as U,writeFile as W}from"node:fs/promises";import{basename as G,dirname as K,join as q,relative as J,resolve as Y,sep as X}from"node:path";const ee=q(`.coreframe/assets`,`asset-publish-report.json`);async function te({alt:n,cacheDir:r,config:i,cwd:a=process.cwd(),env:o=process.env,file:s,id:c,pack:l,store:u,variantWidths:d}){e(c),l!==void 0&&t(l);let f=Y(a,s),p=F(f),h=n?.trim();if((p===`image`||p===`svg`)&&!h)throw Error(`Raster images and SVG assets require non-empty alt text.`);if(p!==`image`&&d)throw Error(`Asset kind "${p}" does not support responsive variant widths.`);await re(p,f,d);let g=await m(a,{allowMissing:!0,migrate:!0});if(g.problems.length>0)return{ok:!1,assets:[],fetched:[],problems:g.problems};let _=await v(a,i),b=u??E({config:_,env:o}),S=await O(f),D={digest:S,filename:G(s),mediaType:p===`image`?M(s):V(s,p),size:(await U(f)).size},k=r??C(o),A=await T({cacheRoot:k,digest:S,env:o,source:f}),j=w(S);if(!await b.has(_.sourceBucket,j)&&(await b.upload(_.sourceBucket,j,A,D.mediaType),!await b.has(_.sourceBucket,j)))throw Error(`Backblaze B2 did not confirm source upload ${j}.`);return y(g.catalog,c,ne({alt:h,kind:p,source:D,variantWidths:d}),l),await x(a,g.catalog),Z({cacheDir:k,config:_,cwd:a,env:o,id:g.migrated?void 0:c,pack:g.migrated?void 0:l,store:b})}function ne({alt:e,kind:t,source:n,variantWidths:r}){return t===`image`?{kind:t,source:n,alt:e,...r?{variantWidths:r}:{}}:t===`svg`?{kind:t,source:n,alt:e}:{kind:t,source:n}}async function re(e,t,n){if(e===`image`){k(n,(await N(t)).width),M(t);return}if(e===`svg`){await z(t);return}if(e===`audio`){await L(t);return}if(e===`video`){await B(t);return}await R(t)}async function Z({cacheDir:e,config:i,cwd:a=process.cwd(),env:s=process.env,id:l,pack:u,store:f,updateManifest:_=!0}={}){u!==void 0&&t(u);let y=await m(a,{migrate:!0}),x=[...y.problems],T=[],O=[];if(x.length>0)return{ok:!1,assets:T,fetched:O,problems:x};y.migrated&&(l=void 0,u=void 0);let k=n(y.catalog),A=l?c(y.catalog,l):void 0;if(l&&!A)return x.push({code:`REFERENCE_MISSING`,message:`Asset "${l}" is not present in ${o}.`,assetId:l,fix:`Run: coreframe assets add <file> --id ${l}`}),{ok:!1,assets:T,fetched:O,problems:x};if(l&&u!==void 0&&A?.pack!==u)return x.push({code:`REFERENCE_MISSING`,message:`Asset "${l}" is not present in asset pack "${u}".`,assetId:l,fix:`Build the asset without --pack or use its owning pack.`}),{ok:!1,assets:T,fetched:O,problems:x};let j=l?A?.pack:u;if(!l&&u!==void 0&&!y.catalog.packs?.[u])return x.push({code:`REFERENCE_MISSING`,message:`Asset pack "${u}" is not present in ${o}.`,fix:`Add an asset with --pack ${u}.`}),{ok:!1,assets:T,fetched:O,problems:x};let M=k.filter(e=>(l===void 0||e.assetId===l)&&(j===void 0?u===void 0||e.pack===void 0:e.pack===j)),N=l!==void 0||u!==void 0?[j]:[void 0,...r(y.catalog)],P=await v(a,i),F=f??E({config:P,env:s}),I=e??C(s),L=new Map;for(let e of N)if(l&&_){let t=await h(a,{allowMissing:!0,pack:e});if(t.problems.length>0)return{ok:!1,assets:T,fetched:O,problems:t.problems};L.set(e,t.manifest)}else L.set(e,ie(e));for(let{assetId:e,entry:t,pack:n}of M){let r=b(e,t);if(r){x.push(r);continue}let i;try{i=await D({bucket:P.sourceBucket,cacheRoot:I,digest:t.source.digest,env:s,store:F})}catch(t){x.push({code:`SOURCE_UNAVAILABLE`,message:`Asset "${e}" source could not be materialized: ${t.message}`,assetId:e,fix:`Check the B2 asset configuration and credential profile "${P.credentialProfile}".`});continue}i.fetched&&O.push(w(t.source.digest));try{let r=await ae({assetId:e,config:P,cwd:a,entry:t,sourcePath:i.path});L.get(n).assets[e]=r,T.push({assetId:e,outputs:p(r)})}catch(n){x.push({code:`INVALID_MEDIA`,message:`Asset "${e}" could not be built: ${n.message}`,assetId:e,file:o,fix:`Replace the source with a supported ${t.kind} file, then run: coreframe assets build --id ${e}`})}}if(_&&x.length===0){for(let[e,t]of L)await S(a,t,e);if(l===void 0&&u===void 0){let e=new Set(r(y.catalog));for(let t of await d(a))e.has(t)||await g(a,t)}}return{ok:x.length===0,assets:T,fetched:O,problems:x}}function ie(e){return{schemaVersion:2,...e===void 0?{}:{pack:e},assets:{}}}async function ae({assetId:e,config:t,cwd:n,entry:r,sourcePath:i}){if(r.kind===`image`){let a=await N(i),o=P(e,r,a.width);if(o)throw Error(o.message);let s=await j({assetId:e,config:t,cwd:n,entry:r,sourcePath:i,sourceDimensions:a});return{kind:`image`,sourceDigest:r.source.digest,alt:r.alt,...a,variants:s}}let a=await I({assetId:e,cwd:n,format:r.kind===`svg`?`svg`:r.kind===`audio`?`mp3`:r.kind===`video`?`mp4`:`json`,mediaType:r.source.mediaType,projectId:t.projectId,sourceDigest:r.source.digest,sourcePath:i});return r.kind===`svg`?{kind:`svg`,sourceDigest:r.source.digest,alt:r.alt,...await z(i),file:a}:r.kind===`audio`?{kind:`audio`,sourceDigest:r.source.digest,...await L(i),file:a}:r.kind===`video`?{kind:`video`,sourceDigest:r.source.digest,...await B(i),file:a}:{kind:`lottie`,sourceDigest:r.source.digest,...await R(i),file:a}}async function Q(e={}){let{cwd:i=process.cwd(),pack:s}=e;s!==void 0&&t(s);let c=await m(i),l=[...c.problems],g=new Set,_=l.length>0;if(l.some(e=>e.code===`SCHEMA_MIGRATION_REQUIRED`))return{ok:!1,catalog:c.catalog,expectedPrefix:``,manifests:new Map,problems:l,requiresFullBuild:!0,selectedEntries:[],staleAssetIds:[]};if(s!==void 0&&!c.catalog.packs?.[s])return l.push({code:`REFERENCE_MISSING`,message:`Asset pack "${s}" is not present in ${o}.`,fix:`Add an asset with --pack ${s}.`}),{ok:!1,catalog:c.catalog,expectedPrefix:``,manifests:new Map,problems:l,requiresFullBuild:!0,selectedEntries:[],staleAssetIds:[]};let y=s===void 0?[void 0,...r(c.catalog)]:[s],b=new Map;for(let e of y){let t=await h(i,{pack:e});l.push(...t.problems),_||=t.problems.length>0,b.set(e,t.manifest)}if(s===void 0){let e=new Set(r(c.catalog));for(let t of await d(i))e.has(t)||(l.push({code:`MANIFEST_STALE`,message:`Generated asset pack manifest "${t}" is not present in the catalog.`,file:a(t),fix:`Run: coreframe assets build`}),_=!0)}let x=`projects/${(await v(i,e.config)).projectId}/assets`,S=n(c.catalog).filter(e=>s===void 0||e.pack===s);for(let{assetId:e,entry:t,pack:n}of S){let r=a(n),i=b.get(n)?.assets[e];if(!i||!f(i,t)){l.push({code:`MANIFEST_STALE`,message:`Asset "${e}" is missing from the generated manifest or does not match its catalog entry.`,assetId:e,file:r,fix:`Run: coreframe assets build --id ${e}`}),g.add(e);continue}if(t.kind===`image`&&i.kind===`image`){let n=P(e,t,i.width);if(n)l.push(n),g.add(e);else{let n=A(t,i.width),a=i.variants.map(e=>e.width);(n.length!==a.length||!n.every((e,t)=>e===a[t]))&&(l.push({code:`MANIFEST_STALE`,message:`Asset "${e}" generated variants do not match its catalog widths.`,assetId:e,file:r,fix:`Run: coreframe assets build --id ${e}`}),g.add(e))}}for(let t of p(i))u(t.path,x)||(l.push({code:`INVALID_VARIANT_PATH`,message:`Asset "${e}" has an invalid generated output path.`,assetId:e,file:t.path,fix:`Run: coreframe assets build --id ${e}`}),g.add(e))}for(let[e,t]of b){let n=e===void 0?c.catalog.assets:c.catalog.packs?.[e]?.assets;for(let r of Object.keys(t.assets))n?.[r]||(l.push({code:`MANIFEST_STALE`,message:`Generated manifest asset "${r}" is not present in its catalog collection.`,assetId:r,file:a(e),fix:`Run: coreframe assets build`}),_=!0)}return{ok:l.length===0,catalog:c.catalog,expectedPrefix:x,manifests:b,problems:l,requiresFullBuild:_,selectedEntries:S,staleAssetIds:[...g].sort()}}async function oe(e={}){let{ok:t,problems:n,requiresFullBuild:r,staleAssetIds:i}=await Q(e);return{ok:t,problems:n,requiresFullBuild:r,staleAssetIds:i}}async function $(e={}){let{cwd:n=process.cwd(),fix:r=!1,pack:a}=e;if(a!==void 0&&t(a),r){let t=await Z(e);if(!t.ok)return{ok:!1,assets:[],problems:t.problems}}let l=await Q(e),{catalog:d,expectedPrefix:m,manifests:h,selectedEntries:g}=l,v=[...l.problems],y=[];if(v.some(e=>e.code===`SCHEMA_MIGRATION_REQUIRED`)||a!==void 0&&!d.packs?.[a])return{ok:!1,assets:y,problems:v};let x=await s(n);for(let{assetId:e,entry:t,pack:r}of g){i.test(e)||v.push({code:`INVALID_ASSET_ID`,message:`Asset ID "${e}" must use lowercase path segments.`,assetId:e,file:o}),(t.kind===`image`||t.kind===`svg`)&&!t.alt.trim()&&v.push({code:`INVALID_ALT`,message:`Asset "${e}" is missing alt text.`,assetId:e,file:o});let a=b(e,t);a&&v.push(a);let s=h.get(r)?.assets[e];if(!s||!f(s,t))continue;let c=await Promise.all(p(s).map(async e=>{let t=u(e.path,m),r=!1;if(t)try{let t=_(n,e.path);r=(await U(t)).size===e.size&&await O(t)===e.hash}catch{r=!1}return{...e,exists:r}}));c.every(e=>e.exists)||v.push({code:`GENERATED_ASSET_MISSING`,message:`Asset "${e}" is missing its expected generated output.`,assetId:e,fix:`Run: coreframe assets build --id ${e}`}),y.push({assetId:e,source:t.source,outputs:c})}for(let e of x){let t=c(d,e.assetId);t?t.entry.kind!==`image`&&t.entry.kind!==`svg`&&v.push({code:`INVALID_REFERENCE`,message:`Markdown image reference "${e.assetId}" cannot use asset kind "${t.entry.kind}".`,assetId:e.assetId,file:e.file}):v.push({code:`INVALID_REFERENCE`,message:`Asset reference "${e.assetId}" is not present in ${o}.`,assetId:e.assetId,file:e.file,fix:`Run: coreframe assets add <file> --id ${e.assetId}`})}return{ok:v.length===0,assets:y,problems:v}}async function se(e={}){let{cwd:t=process.cwd(),env:n=process.env,pack:i}=e,a=[...(await $(e)).problems],o=[],s=[],c=Y(t,ee);if(a.length===0){let a=await v(t,e.config),c=e.store??E({config:a,env:n}),{catalog:l}=await m(t),u=i===void 0?[void 0,...r(l)]:[i];for(let e of u){let{manifest:n}=await h(t,{pack:e});for(let[e,r]of Object.entries(n.assets))for(let n of p(r)){let r=_(t,n.path),i={assetId:e,source:J(t,r).split(X).join(`/`),target:`${a.publicBucket}/${n.path}`,size:n.size};if(await c.has(a.publicBucket,n.path)){s.push(i);continue}await c.upload(a.publicBucket,n.path,r,n.mediaType),o.push(i)}}}let l={ok:a.length===0,uploaded:o,skipped:s,reportPath:c,problems:a};return await H(K(c),{recursive:!0}),await W(c,`${JSON.stringify(l,null,2)}\n`),l}async function ce(e,t={}){return Z({...t,id:e})}function le(e,t=!1){if(t){console.log(JSON.stringify(e,null,2));return}let n=e;n.problems?.length&&console.error(l(n.problems)),console.log(n.ok===!1?`Asset workflow has problems.`:`Asset workflow complete.`)}export{te as addAsset,Z as buildAssets,oe as checkAssetManifests,$ as checkAssets,ce as materializeAsset,le as printAssetResult,se as publishAssets};
|
package/dist/assets.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { AssetBuildEntry, AssetBuildResult, AssetCatalog, AssetCatalogEntry, AssetCatalogPack, AssetFile, AssetKind, AssetManifest, AssetManifestEntry, AssetOutput, AssetOutputStatus, AssetProblem, AssetPublishResult, AssetSource, AssetStatus, AssetStatusEntry, AssetVariant, AudioAssetFile, AudioCatalogEntry, AudioManifestEntry, ImageCatalogEntry, ImageManifestEntry, LoadedAssetCatalog, LoadedAssetManifest, LottieAssetFile, LottieCatalogEntry, LottieManifestEntry, PublishedAsset, SvgAssetFile, SvgCatalogEntry, SvgManifestEntry, SvgViewBox, VideoAssetFile, VideoCatalogEntry, VideoManifestEntry } from "./assets/contracts.js";
|
|
2
2
|
import { assetCatalogEntries, assetCatalogPackNames, assetManifestPath, findCatalogAsset, formatAssetProblems, listAssetManifestPacks, manifestEntryOutputs, readAssetCatalog, readAssetManifest, resolveAssetVariantFile } from "./assets/project.js";
|
|
3
|
-
import { AddAssetOptions, AssetWorkflowOptions, BuildAssetsOptions, CheckAssetsOptions, PublishAssetsOptions, addAsset, buildAssets, checkAssets, materializeAsset, printAssetResult, publishAssets } from "./assets/workflows.js";
|
|
4
|
-
export { AddAssetOptions, type AssetBuildEntry, type AssetBuildResult, type AssetCatalog, type AssetCatalogEntry, type AssetCatalogPack, type AssetFile, type AssetKind, type AssetManifest, type AssetManifestEntry, type AssetOutput, type AssetOutputStatus, type AssetProblem, type AssetPublishResult, type AssetSource, type AssetStatus, type AssetStatusEntry, type AssetVariant, AssetWorkflowOptions, type AudioAssetFile, type AudioCatalogEntry, type AudioManifestEntry, BuildAssetsOptions, CheckAssetsOptions, type ImageCatalogEntry, type ImageManifestEntry, type LoadedAssetCatalog, type LoadedAssetManifest, type LottieAssetFile, type LottieCatalogEntry, type LottieManifestEntry, PublishAssetsOptions, type PublishedAsset, type SvgAssetFile, type SvgCatalogEntry, type SvgManifestEntry, type SvgViewBox, type VideoAssetFile, type VideoCatalogEntry, type VideoManifestEntry, addAsset, assetCatalogEntries, assetCatalogPackNames, assetManifestPath, buildAssets, checkAssets, findCatalogAsset, formatAssetProblems, listAssetManifestPacks, manifestEntryOutputs, materializeAsset, printAssetResult, publishAssets, readAssetCatalog, readAssetManifest, resolveAssetVariantFile };
|
|
3
|
+
import { AddAssetOptions, AssetManifestStatus, AssetWorkflowOptions, BuildAssetsOptions, CheckAssetManifestsOptions, CheckAssetsOptions, PublishAssetsOptions, addAsset, buildAssets, checkAssetManifests, checkAssets, materializeAsset, printAssetResult, publishAssets } from "./assets/workflows.js";
|
|
4
|
+
export { AddAssetOptions, type AssetBuildEntry, type AssetBuildResult, type AssetCatalog, type AssetCatalogEntry, type AssetCatalogPack, type AssetFile, type AssetKind, type AssetManifest, type AssetManifestEntry, AssetManifestStatus, type AssetOutput, type AssetOutputStatus, type AssetProblem, type AssetPublishResult, type AssetSource, type AssetStatus, type AssetStatusEntry, type AssetVariant, AssetWorkflowOptions, type AudioAssetFile, type AudioCatalogEntry, type AudioManifestEntry, BuildAssetsOptions, CheckAssetManifestsOptions, CheckAssetsOptions, type ImageCatalogEntry, type ImageManifestEntry, type LoadedAssetCatalog, type LoadedAssetManifest, type LottieAssetFile, type LottieCatalogEntry, type LottieManifestEntry, PublishAssetsOptions, type PublishedAsset, type SvgAssetFile, type SvgCatalogEntry, type SvgManifestEntry, type SvgViewBox, type VideoAssetFile, type VideoCatalogEntry, type VideoManifestEntry, addAsset, assetCatalogEntries, assetCatalogPackNames, assetManifestPath, buildAssets, checkAssetManifests, checkAssets, findCatalogAsset, formatAssetProblems, listAssetManifestPacks, manifestEntryOutputs, materializeAsset, printAssetResult, publishAssets, readAssetCatalog, readAssetManifest, resolveAssetVariantFile };
|
package/dist/assets.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{assetCatalogEntries as e,assetCatalogPackNames as t,assetManifestPath as n,findCatalogAsset as r,formatAssetProblems as i,listAssetManifestPacks as a,manifestEntryOutputs as o,readAssetCatalog as s,readAssetManifest as c,resolveAssetVariantFile as l}from"./assets/project.js";import{addAsset as u,buildAssets as d,
|
|
1
|
+
import{assetCatalogEntries as e,assetCatalogPackNames as t,assetManifestPath as n,findCatalogAsset as r,formatAssetProblems as i,listAssetManifestPacks as a,manifestEntryOutputs as o,readAssetCatalog as s,readAssetManifest as c,resolveAssetVariantFile as l}from"./assets/project.js";import{addAsset as u,buildAssets as d,checkAssetManifests as f,checkAssets as p,materializeAsset as m,printAssetResult as h,publishAssets as g}from"./assets/workflows.js";export{u as addAsset,e as assetCatalogEntries,t as assetCatalogPackNames,n as assetManifestPath,d as buildAssets,f as checkAssetManifests,p as checkAssets,r as findCatalogAsset,i as formatAssetProblems,a as listAssetManifestPacks,o as manifestEntryOutputs,m as materializeAsset,h as printAssetResult,g as publishAssets,s as readAssetCatalog,c as readAssetManifest,l as resolveAssetVariantFile};
|
package/dist/coreframe.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{assertAssetCredentialProfile as e,configureAssetCredentials as t}from"./assets/credentials.js";import{addAsset as n,buildAssets as r,checkAssets as i,printAssetResult as a,publishAssets as o}from"./assets/workflows.js";import"./assets.js";import{runDrizzleKitCommand as s}from"./db/drizzle-kit.js";import{seedLocalDb as c}from"./db/seed.js";import{migrateLocalDb as l}from"./db/migrate.js";import{resetLocalDb as u}from"./db/reset.js";import{setupLocalDb as d}from"./db/setup.js";import{ensureLocalDb as f}from"./db/ensure.js";import{formatDbErrorMessage as p}from"./db/error.js";import{migrateHeldMigrations as ee}from"./db/migrate-held.js";import{checkSchemaPush as m}from"./db/schema-check.js";import{rotateAccessTokenSigningSecret as h}from"./deploy/access-token-secret.js";import{deployEnvironments as g,tauriReleasePlatforms as _}from"./deploy/config.js";import{buildI18n as te,materializeI18nSnapshot as ne,prepareI18nRelease as re}from"./i18n/workflows.js";import{discoverStagingUrl as ie,reassignStagingHostname as ae}from"./staging.js";import{discardPendingWorkerSecret as oe,inspectWorkerEnvironment as se,parseDeclaredWorkerSecretEnv as ce,queueWorkerSecret as le,queueWorkerSecrets as ue,readDeclaredWorkerSecrets as v}from"./worker-environment.js";import{deployProject as y}from"./deploy.js";import{checkDeployMigrations as b}from"./deploy/check-migrations.js";import{devDebugFeatures as x,devPlatforms as S,runDevServer as C}from"./dev.js";import{validateRecipeName as w}from"./recipes/manifest.js";import{ensureTemplateRemote as T}from"./upgrade/ensure-template-remote.js";import{applyRecipe as E,printAppliedRecipe as D}from"./recipes/apply.js";import{listRecipes as O,printRecipeCatalog as k}from"./recipes/list.js";import{run as A}from"./runner.js";import{typecheckProject as j}from"./typecheck.js";import{checkUpgradeSkillCurrent as M}from"./upgrade/check-skill-current.js";import{fastForwardTemplateFiles as N}from"./upgrade/fast-forward-template-files.js";import{syncCoreframePackages as P}from"./upgrade/sync-coreframe-packages.js";import{array as F,command as I,extendType as L,flag as R,multioption as z,number as B,oneOf as V,option as H,optional as U,positional as W,rest as G,string as K,subcommands as q}from"@alloc/cmd-ts";import*as J from"@clack/prompts";const de=L(V(x),{displayName:`feature`,from:async e=>e}),Y=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],X=[`Use a B2 Multi-Bucket Application Key restricted to the configured private build-object and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),fe=L(K,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),pe=L(K,{displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return w(e)}}),me=L(K,{displayName:`profile`,async from(t){return e(t)}}),Z=L(K,{displayName:`pack`,description:`Asset pack name, such as training-videos.`,async from(e){if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e))throw Error(`Asset pack names must use lowercase hyphen-separated segments.`);return e}}),Q=q({name:`coreframe`,cmds:{assets:q({name:`assets`,cmds:{configure:I({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${X}`,args:{profile:W({type:me,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{J.note(X,`Required B2 key access`);let n=await J.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(J.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);let r=await J.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(J.isCancel(r))throw Error(`Asset credential configuration was cancelled.`);await t({applicationKey:r,applicationKeyId:n.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:I({name:`add`,args:{file:W({type:K,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:H({long:`id`,type:K,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:H({long:`alt`,type:U(K),description:`Required alt text for raster image and SVG assets.`}),pack:H({long:`pack`,type:U(Z),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:H({long:`widths`,type:U(fe),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:r,json:i,pack:o,variantWidths:s})=>a(await n({alt:e,file:t,id:r,pack:o,variantWidths:s}),i)}),build:I({name:`build`,args:{id:H({long:`id`,type:U(K),description:`Build only one logical asset ID.`}),pack:H({long:`pack`,type:U(Z),description:`Build only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>a(await r({id:e,pack:n}),t)}),check:I({name:`check`,args:{fix:R({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:H({long:`pack`,type:U(Z),description:`Check only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await i({fix:e,pack:n});a(r,t),r.ok||(process.exitCode=1)}}),publish:I({name:`publish`,args:{pack:H({long:`pack`,type:U(Z),description:`Publish only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await o({pack:t});a(n,e),n.ok||(process.exitCode=1)}}),status:I({name:`status`,args:{pack:H({long:`pack`,type:U(Z),description:`Report status for only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await i({pack:t});a(n,e),n.ok||(process.exitCode=1)}})}}),i18n:q({name:`i18n`,cmds:{build:I({name:`build`,description:`Extract source messages and compile ignored source-fallback locale modules.`,args:{},handler:async()=>{await te()}}),materialize:I({name:`materialize`,description:`Materialize the immutable i18n snapshot for an exact commit.`,args:{revision:H({long:`revision`,type:U(K),description:`Full commit SHA. Defaults to the checked-out commit.`})},handler:async({revision:e})=>{let t=await ne({revision:e});t&&console.log(`Materialized i18n snapshot ${t.snapshot}.`)}}),prepare:I({name:`prepare`,description:`Fill missing translations, strictly compile, and publish an immutable tagged snapshot.`,args:{tag:H({long:`tag`,type:K,description:`Pushed v* release tag that points to the checked-out commit.`})},handler:async({tag:e})=>{let t=await re({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),deploy:I({name:`deploy`,args:{environment:W({type:V(g),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:R({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:R({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:R({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:z({long:`tauri-local-platform`,type:F(V(_)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:H({long:`tauri-workflow-name`,type:U(K),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:z({long:`tauri-workflow-platform`,type:F(V(_)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:H({long:`tauri-workflow-ref`,type:U(K),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:R({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,tauriLocalPlatforms:i,tauriWorkflowName:a,tauriWorkflowPlatforms:o,tauriWorkflowRef:s,yes:c})=>y([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),staging:q({name:`staging`,cmds:{reassign:I({name:`reassign`,args:{json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ae();if(e){console.log(JSON.stringify({...t,notices:Y}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Y.join(` `)}`)}}),url:I({name:`url`,args:{json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ie();console.log(e?JSON.stringify({url:t}):t)}})}}),secrets:q({name:`secrets`,cmds:{"rotate-access-token":I({name:`rotate-access-token`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:R({long:`yes`,short:`y`,description:`Confirm immediate signing-secret replacement and invalidation of outstanding access JWTs.`,defaultValue:()=>!1})},handler:async({environment:e,yes:t})=>{if(!t)throw Error(`Access-token signing-secret rotation requires --yes because it immediately invalidates outstanding access JWTs.`);await h({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:I({name:`status`,args:{environment:W({type:U(V(g)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await se({environment:e});console.log(t?JSON.stringify(n):he(n))}}),set:I({name:`set`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:W({type:U(K),displayName:`name`,description:`Declared Worker secret name; omit to configure known secrets.`}),bulk:R({long:`bulk`,description:`Queue known secrets from pasted or piped dotenv-formatted contents.`,defaultValue:()=>!1})},handler:async({environment:e,name:t,bulk:n})=>{if(n&&t)throw Error(`Use either a secret name or --bulk, not both.`);if(t){await le({environment:e,name:t,value:await ge(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await v(),i=n?await _e(r):await $(r,e);await ue({environment:e,values:i});let a=Object.keys(i).sort();console.log(a.length>0?`Queued ${a.join(`, `)} for ${e}. Run coreframe deploy ${e} to apply.`:`No ${e} Worker secret updates were queued.`)}}),discard:I({name:`discard`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:W({type:K,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await oe({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),typecheck:I({name:`typecheck`,args:{},handler:j}),dev:I({name:`dev`,args:{debug:H({long:`debug`,type:U(de),description:`Launch a development feature in isolated debug mode.`}),https:R({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),host:H({long:`host`,type:U(K),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),managed:R({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:R({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),platform:W({type:U(V(S)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:W({type:U(K),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:H({long:`port`,type:U(B),description:`Port for the web development server.`}),verbose:R({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o,port:s,verbose:c})=>C({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o??`web`,verbose:c,webPort:s})}),upgrade:q({name:`upgrade`,cmds:{"ensure-template-remote":I({name:`ensure-template-remote`,args:{remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:R({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>T({fetch:!e,remote:t})}),"check-skill-current":I({name:`check-skill-current`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:R({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=M({apply:e,target:t})}}),"fast-forward-template-files":I({name:`fast-forward-template-files`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),base:H({long:`base`,type:U(K),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:R({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>N({apply:e,base:t,target:n})}),"sync-coreframe-packages":I({name:`sync-coreframe-packages`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:R({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>P({apply:e,target:t})})}}),recipes:q({name:`recipes`,cmds:{apply:I({name:`apply`,args:{recipe:W({type:pe,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:R({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>D(E({fetch:!e,name:t,remote:n,target:r}))}),list:I({name:`list`,args:{target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:R({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>k(O({fetch:!e,remote:t,target:n}))})}}),db:q({name:`db`,cmds:{ensure:I({name:`ensure`,args:{},handler:f}),generate:I({name:`generate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>s(`generate`,e)}),migrate:I({name:`migrate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>s(`migrate`,e)}),"migrate-held":I({name:`migrate-held`,args:{confirm:H({long:`confirm`,type:U(V([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>ee({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":I({name:`migrate-local`,args:{},handler:l}),"migrations-check":I({name:`migrations-check`,args:{},handler:b}),reset:I({name:`reset`,args:{},handler:u}),seed:I({name:`seed`,args:{},handler:()=>c()}),"schema-check":I({name:`schema-check`,args:{seed:R({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>m({seed:e})}),setup:I({name:`setup`,args:{},handler:()=>d()}),studio:I({name:`studio`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>s(`studio`,e)})}})}});import.meta.main&&A(Q,{formatMessage:process.argv[2]===`db`?p:void 0});function he(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
|
|
2
|
+
import{assertAssetCredentialProfile as e,configureAssetCredentials as t}from"./assets/credentials.js";import{addAsset as n,buildAssets as r,checkAssets as i,printAssetResult as a,publishAssets as o}from"./assets/workflows.js";import"./assets.js";import{runDrizzleKitCommand as s}from"./db/drizzle-kit.js";import{seedLocalDb as c}from"./db/seed.js";import{migrateLocalDb as l}from"./db/migrate.js";import{resetLocalDb as u}from"./db/reset.js";import{setupLocalDb as d}from"./db/setup.js";import{ensureLocalDb as f}from"./db/ensure.js";import{formatDbErrorMessage as p}from"./db/error.js";import{migrateHeldMigrations as ee}from"./db/migrate-held.js";import{checkSchemaPush as m}from"./db/schema-check.js";import{rotateAccessTokenSigningSecret as h}from"./deploy/access-token-secret.js";import{deployEnvironments as g,tauriReleasePlatforms as _}from"./deploy/config.js";import{buildI18n as te,materializeI18nSnapshot as ne,prepareI18nRelease as re}from"./i18n/workflows.js";import{discoverStagingUrl as ie,reassignStagingHostname as ae}from"./staging.js";import{discardPendingWorkerSecret as oe,inspectWorkerEnvironment as se,parseDeclaredWorkerSecretEnv as ce,queueWorkerSecret as le,queueWorkerSecrets as ue,readDeclaredWorkerSecrets as v}from"./worker-environment.js";import{deployProject as y}from"./deploy.js";import{checkDeployMigrations as b}from"./deploy/check-migrations.js";import{devDebugFeatures as x,devPlatforms as S,runDevServer as C}from"./dev.js";import{validateRecipeName as w}from"./recipes/manifest.js";import{ensureTemplateRemote as T}from"./upgrade/ensure-template-remote.js";import{applyRecipe as E,printAppliedRecipe as D}from"./recipes/apply.js";import{listRecipes as O,printRecipeCatalog as k}from"./recipes/list.js";import{run as A}from"./runner.js";import{typecheckProject as j}from"./typecheck.js";import{checkUpgradeSkillCurrent as M}from"./upgrade/check-skill-current.js";import{fastForwardTemplateFiles as N}from"./upgrade/fast-forward-template-files.js";import{syncCoreframePackages as P}from"./upgrade/sync-coreframe-packages.js";import{array as F,command as I,extendType as L,flag as R,multioption as z,number as B,oneOf as V,option as H,optional as U,positional as W,rest as G,string as K,subcommands as q}from"@alloc/cmd-ts";import*as J from"@clack/prompts";const de=L(V(x),{displayName:`feature`,from:async e=>e}),Y=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],X=[`Use a B2 Multi-Bucket Application Key restricted to the configured private build-object and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),fe=L(K,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),pe=L(K,{displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return w(e)}}),me=L(K,{displayName:`profile`,async from(t){return e(t)}}),Z=L(K,{displayName:`pack`,description:`Asset pack name, such as training-videos.`,async from(e){if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e))throw Error(`Asset pack names must use lowercase hyphen-separated segments.`);return e}}),Q=q({name:`coreframe`,cmds:{assets:q({name:`assets`,cmds:{configure:I({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${X}`,args:{profile:W({type:me,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{J.note(X,`Required B2 key access`);let n=await J.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(J.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);let r=await J.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(J.isCancel(r))throw Error(`Asset credential configuration was cancelled.`);await t({applicationKey:r,applicationKeyId:n.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:I({name:`add`,args:{file:W({type:K,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:H({long:`id`,type:K,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:H({long:`alt`,type:U(K),description:`Required alt text for raster image and SVG assets.`}),pack:H({long:`pack`,type:U(Z),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:H({long:`widths`,type:U(fe),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:r,json:i,pack:o,variantWidths:s})=>a(await n({alt:e,file:t,id:r,pack:o,variantWidths:s}),i)}),build:I({name:`build`,args:{id:H({long:`id`,type:U(K),description:`Build only one logical asset ID.`}),pack:H({long:`pack`,type:U(Z),description:`Build only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>a(await r({id:e,pack:n}),t)}),check:I({name:`check`,args:{fix:R({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:H({long:`pack`,type:U(Z),description:`Check only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await i({fix:e,pack:n});a(r,t),r.ok||(process.exitCode=1)}}),publish:I({name:`publish`,args:{pack:H({long:`pack`,type:U(Z),description:`Publish only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await o({pack:t});a(n,e),n.ok||(process.exitCode=1)}}),status:I({name:`status`,args:{pack:H({long:`pack`,type:U(Z),description:`Report status for only one named asset pack.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await i({pack:t});a(n,e),n.ok||(process.exitCode=1)}})}}),i18n:q({name:`i18n`,cmds:{build:I({name:`build`,description:`Extract source messages or materialize an exact release catalog snapshot.`,args:{},handler:async()=>{await te()}}),materialize:I({name:`materialize`,description:`Materialize the immutable i18n snapshot for an exact commit.`,args:{revision:H({long:`revision`,type:U(K),description:`Full commit SHA. Defaults to the checked-out commit.`})},handler:async({revision:e})=>{let t=await ne({revision:e});t&&console.log(`Materialized i18n snapshot ${t.snapshot}.`)}}),prepare:I({name:`prepare`,description:`Fill missing translations, strictly compile, and publish an immutable tagged snapshot.`,args:{tag:H({long:`tag`,type:K,description:`Pushed v* release tag that points to the checked-out commit.`})},handler:async({tag:e})=>{let t=await re({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),deploy:I({name:`deploy`,args:{environment:W({type:V(g),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:R({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:R({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:R({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:z({long:`tauri-local-platform`,type:F(V(_)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:H({long:`tauri-workflow-name`,type:U(K),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:z({long:`tauri-workflow-platform`,type:F(V(_)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:H({long:`tauri-workflow-ref`,type:U(K),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:R({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,tauriLocalPlatforms:i,tauriWorkflowName:a,tauriWorkflowPlatforms:o,tauriWorkflowRef:s,yes:c})=>y([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),staging:q({name:`staging`,cmds:{reassign:I({name:`reassign`,args:{json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ae();if(e){console.log(JSON.stringify({...t,notices:Y}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Y.join(` `)}`)}}),url:I({name:`url`,args:{json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ie();console.log(e?JSON.stringify({url:t}):t)}})}}),secrets:q({name:`secrets`,cmds:{"rotate-access-token":I({name:`rotate-access-token`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:R({long:`yes`,short:`y`,description:`Confirm immediate signing-secret replacement and invalidation of outstanding access JWTs.`,defaultValue:()=>!1})},handler:async({environment:e,yes:t})=>{if(!t)throw Error(`Access-token signing-secret rotation requires --yes because it immediately invalidates outstanding access JWTs.`);await h({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:I({name:`status`,args:{environment:W({type:U(V(g)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:R({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await se({environment:e});console.log(t?JSON.stringify(n):he(n))}}),set:I({name:`set`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:W({type:U(K),displayName:`name`,description:`Declared Worker secret name; omit to configure known secrets.`}),bulk:R({long:`bulk`,description:`Queue known secrets from pasted or piped dotenv-formatted contents.`,defaultValue:()=>!1})},handler:async({environment:e,name:t,bulk:n})=>{if(n&&t)throw Error(`Use either a secret name or --bulk, not both.`);if(t){await le({environment:e,name:t,value:await ge(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await v(),i=n?await _e(r):await $(r,e);await ue({environment:e,values:i});let a=Object.keys(i).sort();console.log(a.length>0?`Queued ${a.join(`, `)} for ${e}. Run coreframe deploy ${e} to apply.`:`No ${e} Worker secret updates were queued.`)}}),discard:I({name:`discard`,args:{environment:W({type:V(g),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:W({type:K,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await oe({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),typecheck:I({name:`typecheck`,args:{},handler:j}),dev:I({name:`dev`,args:{debug:H({long:`debug`,type:U(de),description:`Launch a development feature in isolated debug mode.`}),https:R({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),host:H({long:`host`,type:U(K),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),managed:R({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:R({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),platform:W({type:U(V(S)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:W({type:U(K),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:H({long:`port`,type:U(B),description:`Port for the web development server.`}),verbose:R({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o,port:s,verbose:c})=>C({debug:e,device:t,host:n,https:r,managed:i,noManaged:a,platform:o??`web`,verbose:c,webPort:s})}),upgrade:q({name:`upgrade`,cmds:{"ensure-template-remote":I({name:`ensure-template-remote`,args:{remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:R({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>T({fetch:!e,remote:t})}),"check-skill-current":I({name:`check-skill-current`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:R({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=M({apply:e,target:t})}}),"fast-forward-template-files":I({name:`fast-forward-template-files`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),base:H({long:`base`,type:U(K),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:R({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>N({apply:e,base:t,target:n})}),"sync-coreframe-packages":I({name:`sync-coreframe-packages`,args:{target:H({long:`target`,type:K,description:`Target Coreframe template git ref.`}),apply:R({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>P({apply:e,target:t})})}}),recipes:q({name:`recipes`,cmds:{apply:I({name:`apply`,args:{recipe:W({type:pe,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:R({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>D(E({fetch:!e,name:t,remote:n,target:r}))}),list:I({name:`list`,args:{target:H({long:`target`,type:U(K),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:H({long:`remote`,type:K,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:R({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>k(O({fetch:!e,remote:t,target:n}))})}}),db:q({name:`db`,cmds:{ensure:I({name:`ensure`,args:{},handler:f}),generate:I({name:`generate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>s(`generate`,e)}),migrate:I({name:`migrate`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>s(`migrate`,e)}),"migrate-held":I({name:`migrate-held`,args:{confirm:H({long:`confirm`,type:U(V([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>ee({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":I({name:`migrate-local`,args:{},handler:l}),"migrations-check":I({name:`migrations-check`,args:{},handler:b}),reset:I({name:`reset`,args:{},handler:u}),seed:I({name:`seed`,args:{},handler:()=>c()}),"schema-check":I({name:`schema-check`,args:{seed:R({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>m({seed:e})}),setup:I({name:`setup`,args:{},handler:()=>d()}),studio:I({name:`studio`,args:{args:G({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>s(`studio`,e)})}})}});import.meta.main&&A(Q,{formatMessage:process.argv[2]===`db`?p:void 0});function he(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
|
|
3
3
|
`)}async function ge(e){if(!process.stdin.isTTY){let e=``;for await(let t of process.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await J.password({message:`Enter the new value for ${e}`});if(J.isCancel(t))throw J.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}async function $(e,t){if(!process.stdin.isTTY)throw Error(`Interactive secret setup requires a terminal. Provide a secret name or use --bulk with piped dotenv contents.`);if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let n={};for(let r of e){let e=r.requiredIn.includes(t),i=await J.password({message:`${r.name}: ${r.description}${e?` (required)`:` (optional; leave blank to skip)`}`,validate:n=>e&&!n?.trim()?`${r.name} is required in ${t}.`:void 0});if(J.isCancel(i))throw J.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);i.trim()&&(n[r.name]=i)}return n}async function _e(e){if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let t=process.stdin.isTTY?await J.multiline({message:`Paste dotenv-formatted Worker secrets. Press Enter twice to submit.`,validate:e=>e?.trim()?void 0:`Paste at least one dotenv entry.`}):await ve();if(J.isCancel(t))throw J.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);let{ignoredNames:n,values:r}=ce(t,e);return n.length>0&&J.log.info(`Ignored non-secret or undeclared names: ${n.join(`, `)}.`),r}async function ve(){let e=``;for await(let t of process.stdin)e+=t.toString();return e}export{Q as coreframeCli};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region dev-timing.d.ts
|
|
2
|
+
declare const devStartupTimingsEnv = "COREFRAME_DEV_TIMINGS";
|
|
3
|
+
declare const devStartupStartedAtEnv = "COREFRAME_DEV_STARTED_AT";
|
|
4
|
+
type DevStartupTimingOptions = {
|
|
5
|
+
env?: NodeJS.ProcessEnv;
|
|
6
|
+
now?: () => number;
|
|
7
|
+
write?: (message: string) => void;
|
|
8
|
+
};
|
|
9
|
+
declare function createDevStartupTiming({
|
|
10
|
+
env,
|
|
11
|
+
now,
|
|
12
|
+
write
|
|
13
|
+
}?: DevStartupTimingOptions): {
|
|
14
|
+
environment: {
|
|
15
|
+
COREFRAME_DEV_STARTED_AT: string;
|
|
16
|
+
COREFRAME_DEV_TIMINGS: string;
|
|
17
|
+
} | {
|
|
18
|
+
COREFRAME_DEV_STARTED_AT?: undefined;
|
|
19
|
+
COREFRAME_DEV_TIMINGS?: undefined;
|
|
20
|
+
};
|
|
21
|
+
measure<Result>(name: string, operation: () => Promise<Result>): Promise<Result>;
|
|
22
|
+
report(): void;
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { createDevStartupTiming, devStartupStartedAtEnv, devStartupTimingsEnv };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=`COREFRAME_DEV_TIMINGS`,t=`COREFRAME_DEV_STARTED_AT`;function n({env:n=process.env,now:r=Date.now,write:i=console.log}={}){let a=n[e]===`1`,o=r(),s=[];return{environment:a?{[t]:String(o),[e]:`1`}:{},async measure(e,t){if(!a)return t();let n=r();try{return await t()}finally{s.push({duration:Math.max(0,Math.round(r()-n)),name:e})}},report(){if(!a)return;let e=Math.max(0,Math.round(r()-o)),t=s.map(({duration:e,name:t})=>`${t}=${e}ms`).join(` `);i(`[coreframe:startup] preflight=${e}ms${t?` ${t}`:``}`)}}}export{n as createDevStartupTiming,t as devStartupStartedAtEnv,e as devStartupTimingsEnv};
|
package/dist/dev.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{readProjectConfig as e}from"./config.js";import{fs as t,net as n}from"./environment.js";import{ProjectPostgresAlreadyRunningError as r,startProjectPostgres as i,stopProjectPostgres as a}from"./db/local-postgres.js";import{resolveMobileDevHost as
|
|
2
|
+
import{readProjectConfig as e}from"./config.js";import{fs as t,net as n}from"./environment.js";import{ProjectPostgresAlreadyRunningError as r,startProjectPostgres as i,stopProjectPostgres as a}from"./db/local-postgres.js";import{ensureDevI18nCatalogs as o}from"./i18n/workflows.js";import{resolveMobileDevHost as s,selectMobileDevDevice as ee}from"./dev-device.js";import{devHttpsCertEnv as te,devHttpsKeyEnv as c,prepareDevHttps as l}from"./dev-https.js";import{acquireDevLock as u}from"./dev-lock.js";import{createDevStartupTiming as d}from"./dev-timing.js";import{managedDevEnv as ne}from"./managed-dev-protocol.js";import{isManagedDevCheckout as re,isPrimaryCheckout as ie}from"./managed-dev.js";import{createTauriDevOutput as ae}from"./tauri-dev-output.js";import f from"node:path";import p from"nano-spawn";import{finished as m}from"node:stream/promises";import*as h from"@clack/prompts";import g from"node:process";import{once as _}from"node:events";import{determineAgent as v}from"@vercel/detect-agent";import{createPrefixStream as y,supervise as b}from"procband";const x=[`web`,`desktop`,`ios`,`android`],S=[`managed-dev-overlay`],C=`VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG`;function w(e){let t=e.dev?.platforms??[`web`];for(let e of t)if(!x.includes(e))throw Error(`Invalid development platform "${String(e)}". Expected one of: ${x.join(`, `)}.`);return[...new Set(t)]}const oe=f.resolve(`node_modules`,`.bin`),T=g.platform===`win32`?`pnpm.cmd`:`pnpm`,se=g.platform===`win32`?`portless.cmd`:`portless`,ce=g.platform===`win32`?`react-router.cmd`:`react-router`,le=g.platform===`win32`?`turso.cmd`:`turso`;async function E({cwd:r=g.cwd(),debug:i,device:a,env:_=g.env,host:x,https:S=!1,interactive:w=g.stdin.isTTY===!0,managed:E=!1,noManaged:F=!1,platform:I=`web`,verbose:de=!1,webPort:L}={}){let R=d({env:_}),fe=_.PATH??_.Path??``,z=I===`web`?P(L??_.COREFRAME_WEB_PORT):void 0,B,V,H,U,W,G=!1,K,q=_;if(E&&F)throw Error(`Cannot use --managed and --no-managed together.`);if(i===`managed-dev-overlay`&&E)throw Error(`Cannot use --managed with --debug managed-dev-overlay.`);if(S&&I!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(a!==void 0&&I!==`ios`&&I!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);if(I===`web`&&_.TAURI_ENV_PLATFORM!==void 0&&_.COREFRAME_TAURI_DEV!==`1`){let e=_.TAURI_ENV_PLATFORM===`ios`||_.TAURI_ENV_PLATFORM===`android`?_.TAURI_ENV_PLATFORM:`desktop`;throw Error(`Direct Tauri development is not supported. Run \`pnpm dev ${e}\` instead.`)}let J=await R.measure(`dev-lock`,()=>u({cwd:r,interactive:w}));if(!J)return;let Y=()=>{G||(G=!0,V?.kill(`SIGTERM`),W?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),B?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),U?.kill(`SIGTERM`))},X=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>{K??=e,Y()};return g.on(e,t),{handler:t,signal:e}}),Z=async e=>{let t=b(e);V=t;try{await t.expectSuccess()}catch(e){if(!G)throw e}finally{V===t&&(V=void 0)}};try{let u=I===`ios`||I===`android`?I:void 0,d=u?await ee({env:_,interactive:w,platform:u,target:a}):void 0,O=u&&d?await s({device:d,host:x,interactive:w,platform:u}):void 0,P=O?!0:x,[L,V,K]=await Promise.all([R.measure(`config`,()=>e({cwd:r})),R.measure(`routing`,async()=>I===`web`&&_.PORTLESS!==`0`&&_.TAURI_ENV_PLATFORM===void 0&&!(await v()).isAgent&&await ie(r)),R.measure(`managed`,async()=>i!==`managed-dev-overlay`&&(E||w&&!F)&&await re(r))]);await R.measure(`i18n`,()=>o({cwd:r,projectConfig:L}));let X=await R.measure(`https`,async()=>S&&!V?l({cwd:r}):void 0);q={..._,...R.environment,...i===`managed-dev-overlay`?{[C]:`1`}:void 0,...I===`web`?void 0:{COREFRAME_TAURI_DEV:`1`,TAURI_ENV_PLATFORM:M(I),...O?{TAURI_DEV_HOST:O}:void 0},...X?{[te]:X.cert,[c]:X.key}:void 0};let Q=async()=>{let e=y({label:`web`}),t=y({color:`red`,label:`web`});e.pipe(g.stdout,{end:!1}),t.pipe(g.stderr,{end:!1}),W=p(V?se:ce,V?ue({host:P,port:z}):N({host:P,port:z}),{cwd:r,env:{...q,CLOUDFLARE_ENV:`development`,PATH:oe+f.delimiter+fe},stdin:`inherit`});let n=Promise.allSettled([D(W.stdout,e),D(W.stderr,t)]);try{await W;let e=(await n).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!G)throw e}finally{await n,e.end(),t.end(),await Promise.allSettled([m(e),m(t)]),W=void 0}},$=async()=>{if(I===`web`){await Q();return}let e=Q().then(()=>{if(!G)throw Error(`The Vite development server stopped while Tauri was still running.`)}),t,n;if(I===`ios`&&!de){n=y({label:`ios`}),n.pipe(g.stdout,{end:!1});try{t=await ae({output:n}),h.log.info(`Full iOS log: ${t.logFile}`)}catch{n.end(),n=void 0,h.log.warn(`Could not create the temporary iOS log; showing full Tauri output.`)}}B=p(T,j(I,d?.name,O),{cwd:r,env:_,stdio:t?[`inherit`,`pipe`,`pipe`]:`inherit`});let i=t?.consume(B),a=B.catch(async e=>{throw G||(await i,await t?.reportFailure()),e});try{await Promise.race([e,a])}finally{Y(),await Promise.allSettled([e,B,i]),await t?.close(),n?.end(),B=void 0}};if(K&&(q={...q,[ne]:`1`}),G||L.database?.dialect===`sqlite`&&(await R.measure(`database`,async()=>{let e=await n.getAvailablePort(),i=f.resolve(r,`.coreframe`),a=f.join(i,`turso.db`);await t.mkdir(i,{recursive:!0}),q={...q,TURSO_DATABASE_URL:`http://127.0.0.1:${e}`,TURSO_AUTH_TOKEN:`dev`},U=b({name:`turso`,command:le,args:[`dev`,`--port`,String(e),`--db-file`,a],cwd:r,env:_}),await U.waitFor(`listening`)}),await R.measure(`schema`,()=>Z({name:`db`,command:T,args:[`db`,`ensure`],cwd:r,env:q,prefix:!1})),G))return;if(A(L)){let e=y({label:`postgres`});e.pipe(g.stdout,{end:!1});try{let t=await R.measure(`database`,()=>k({config:L,cwd:r,env:q,failIfRunning:!0,interactive:w,isStopping:()=>G,postgresOutput:e,takeoverApproved:J.takeoverApproved}));if(!t)return;H=t,q=t.env;try{G||await R.measure(`schema`,()=>Z({name:`db`,command:T,args:[`db`,`ensure`],cwd:r,env:q,prefix:!1})),G||(R.report(),await $())}finally{await t[Symbol.asyncDispose](),H===t&&(H=void 0)}}finally{e.end()}return}R.report(),await $()}finally{Y();let e;try{await H?.[Symbol.asyncDispose]()}catch(t){e=t}finally{for(let{handler:e,signal:t}of X)g.off(t,e);K&&(g.exitCode??=K===`SIGINT`?130:143)}O(e),await J.release()}}async function D(e,t){for await(let n of e)t.write(`${n}\n`)||await _(t,`drain`)}function O(e){if(e)throw e}async function k({interactive:e,isStopping:t,takeoverApproved:n,...o}){try{return await i(o)}catch(s){if(!(s instanceof r)||!e)throw s;if(!n){let e=await h.confirm({initialValue:!1,message:`PostgreSQL is already running for this project (PID ${s.pid}). Stop it and start here?`});if(h.isCancel(e)||!e){h.cancel(`Keeping the existing PostgreSQL process.`);return}}return await a(s),t()?void 0:i(o)}}function A(e){return(e.database?.dialect??`postgres`)===`postgres`}function j(e,t,n){return[`exec`,`tauri`,...e===`desktop`?[]:[e],`dev`,`--config`,JSON.stringify({build:{beforeDevCommand:``}}),...n===void 0?[]:[`--host=${n}`],...t===void 0?[]:[t]]}function M(e){return e===`desktop`?g.platform===`win32`?`windows`:g.platform:e}function N({host:e,port:t}){return[`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)]]}function ue({host:e,port:t}){return[`run`,...t===void 0?[]:[`--app-port`,String(t)],`react-router`,...N({host:e,port:void 0})]}function P(e){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw Error(`COREFRAME_WEB_PORT must be a valid TCP port.`);return t}export{S as devDebugFeatures,x as devPlatforms,C as managedDevOverlayDebugEnv,w as resolveDevPlatforms,E as runDevServer};
|
package/dist/i18n/catalogs.d.ts
CHANGED
|
@@ -6,9 +6,8 @@ type ResolvedI18nConfig = Required<Pick<I18nConfig, "catalogs" | "locales" | "so
|
|
|
6
6
|
directory: string;
|
|
7
7
|
};
|
|
8
8
|
declare function catalogRelativePath(config: ResolvedI18nConfig, locale: string, catalog: string): string;
|
|
9
|
-
declare function compiledRelativePath(config: ResolvedI18nConfig, locale: string, catalog: string): string;
|
|
10
9
|
declare function runLinguiExtract(cwd: string): Promise<void>;
|
|
11
|
-
declare function
|
|
10
|
+
declare function validateLinguiCompile({
|
|
12
11
|
config,
|
|
13
12
|
cwd,
|
|
14
13
|
strict,
|
|
@@ -58,4 +57,4 @@ declare function assertCompleteCatalogs({
|
|
|
58
57
|
declare function readRichCatalog(path: string): Promise<RichCatalog>;
|
|
59
58
|
declare function writeRichCatalog(path: string, catalog: RichCatalog): Promise<void>;
|
|
60
59
|
//#endregion
|
|
61
|
-
export { ResolvedI18nConfig, applyGeneratedTranslations, assertCompleteCatalogs, catalogRelativePath, collectMissingTranslations,
|
|
60
|
+
export { ResolvedI18nConfig, applyGeneratedTranslations, assertCompleteCatalogs, catalogRelativePath, collectMissingTranslations, generateMissingTranslations, readRichCatalog, runLinguiExtract, validateLinguiCompile, writeRichCatalog };
|
package/dist/i18n/catalogs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{importProjectDependency as e}from"../project.js";import{resolveProjectArtifact as t}from"./paths.js";import{copyFile as n,mkdir as r,readFile as i,rename as a,writeFile as
|
|
1
|
+
import{importProjectDependency as e}from"../project.js";import{resolveProjectArtifact as t}from"./paths.js";import{copyFile as n,mkdir as r,readFile as i,rename as a,rm as o,writeFile as s}from"node:fs/promises";import{dirname as c,join as l}from"node:path";import u from"nano-spawn";function d(e,t,n){return`${e.directory}/${t}/${n}.json`}function f(e,t,n){return`${e.directory}/${t}/${n}.mjs`}async function p(e){await u(`pnpm`,[`exec`,`lingui`,`extract`],{cwd:e,stdio:`inherit`})}async function m({config:e,cwd:i,strict:a,temporaryDirectory:s}){let p=[];try{for(let a of e.locales)for(let o of e.catalogs){let u=t(i,d(e,a,o)),f=await y(u),m=Object.fromEntries(Object.entries(f).filter(([,e])=>!e.obsolete)),h=l(s,`${a}-${o}.json`);await r(c(h),{recursive:!0}),await n(u,h),p.push({path:u,backup:h}),await b(u,m)}await u(`pnpm`,[`exec`,`lingui`,`compile`,...a?[`--strict`]:[]],{cwd:i,stdio:`inherit`})}finally{try{for(let{path:e,backup:t}of p)await n(t,e)}finally{for(let n of e.locales)for(let r of e.catalogs)await o(t(i,f(e,n,r)),{force:!0})}}}async function h({config:e,cwd:n}){let r=[];for(let i of e.locales)if(i!==e.sourceLocale)for(let a of e.catalogs){let o=await y(t(n,d(e,i,a)));for(let[e,t]of Object.entries(o)){if(t.obsolete||t.translation?.trim())continue;let n=t.message;if(typeof n!=`string`||!n)throw Error(`Missing source message metadata for ${i}:${e}.`);r.push({catalog:a,comments:t.comments?.filter(e=>typeof e==`string`)??[],context:t.context,id:e,locale:i,message:n,origins:t.origin?.map(([e,t])=>t?`${e}:${t}`:e)??[],placeholders:Object.keys(t.placeholders??{}).sort()})}}return r.sort((e,t)=>T(e).localeCompare(T(t)))}async function g({config:e,cwd:t,messages:n,env:r=process.env}){if(n.length===0)return{translations:[],version:1};if(!e.generator)throw Error(`I18n preparation found ${n.length} missing translations, but no generator is configured.`);let i={messages:n,sourceLocale:e.sourceLocale,version:1};return x(await S({args:e.generator.args??[],command:e.generator.command,cwd:t,env:r,input:JSON.stringify(i)}))}async function _({config:n,cwd:r,missing:i,response:a}){let o=new Map(i.map(e=>[T(e),e])),s=new Map;for(let e of a.translations){let t=T(e);if(!o.has(t))throw Error(`Translation generator returned unexpected entry ${e.locale}:${e.catalog}:${e.id}.`);if(s.has(t))throw Error(`Translation generator returned duplicate entry ${e.locale}:${e.catalog}:${e.id}.`);if(!e.translation.trim())throw Error(`Translation generator returned an empty entry ${e.locale}:${e.id}.`);s.set(t,e.translation)}let c=[...o.keys()].filter(e=>!s.has(e));if(c.length>0)throw Error(`Translation generator omitted ${c.length} required entries.`);let l=await e(`@lingui/message-utils/compileMessage`,r);for(let e of i){let t=s.get(T(e));C({compileMessage:l,id:e.id,locale:e.locale,source:e.message,translation:t})}for(let e of n.locales)if(e!==n.sourceLocale)for(let i of n.catalogs){let a=t(r,d(n,e,i)),o=await y(a),c=!1;for(let[t,n]of Object.entries(o)){let r=s.get(T({catalog:i,id:t,locale:e}));if(r!==void 0){if(n.translation?.trim())throw Error(`Refusing to overwrite preserved translation ${e}:${t}.`);n.translation=r,c=!0}}c&&await b(a,o)}}async function v({config:n,cwd:r}){let i=await h({config:n,cwd:r});if(i.length>0)throw Error(`I18n catalogs remain incomplete: ${i.length} translations are missing.`);let a=await e(`@lingui/message-utils/compileMessage`,r);for(let e of n.locales)if(e!==n.sourceLocale)for(let i of n.catalogs){let o=await y(t(r,d(n,e,i)));for(let[t,n]of Object.entries(o))if(!n.obsolete){if(typeof n.message!=`string`||typeof n.translation!=`string`)throw Error(`Incomplete source metadata for active translation ${e}:${t}.`);C({compileMessage:a,id:t,locale:e,source:n.message,translation:n.translation})}}}async function y(e){let t=JSON.parse(await i(e,`utf8`));if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Lingui rich JSON catalog must be an object: ${e}.`);for(let[n,r]of Object.entries(t)){if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`Invalid Lingui rich JSON message ${n} in ${e}.`);let t=r;if(t.translation!==void 0&&typeof t.translation!=`string`)throw Error(`Invalid translation value for ${n} in ${e}.`);if(t.message!==void 0&&t.message!==null&&typeof t.message!=`string`)throw Error(`Invalid source message value for ${n} in ${e}.`);if(t.context!==void 0&&typeof t.context!=`string`)throw Error(`Invalid context value for ${n} in ${e}.`);if(t.obsolete!==void 0&&typeof t.obsolete!=`boolean`)throw Error(`Invalid obsolete marker for ${n} in ${e}.`);if(t.comments!==void 0&&(!Array.isArray(t.comments)||t.comments.some(e=>typeof e!=`string`)))throw Error(`Invalid comments for ${n} in ${e}.`);if(t.origin!==void 0&&(!Array.isArray(t.origin)||t.origin.some(e=>!Array.isArray(e)||typeof e[0]!=`string`||e[1]!==void 0&&typeof e[1]!=`number`)))throw Error(`Invalid origins for ${n} in ${e}.`);if(t.placeholders!==void 0&&(!t.placeholders||typeof t.placeholders!=`object`||Array.isArray(t.placeholders)))throw Error(`Invalid placeholders for ${n} in ${e}.`)}return t}async function b(e,t){await r(c(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;await s(n,`${JSON.stringify(t,null,2)}\n`),await a(n,e)}function x(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Translation generator returned invalid JSON.`)}if(!t||typeof t!=`object`||t.version!==1||!Array.isArray(t.translations))throw Error(`Translation generator returned an invalid response envelope.`);for(let e of t.translations)if(!e||typeof e!=`object`||typeof e.id!=`string`||typeof e.catalog!=`string`||typeof e.locale!=`string`||typeof e.translation!=`string`)throw Error(`Translation generator returned an invalid translation entry.`);return t}function S({args:e,command:t,cwd:n,env:r,input:i}){return u(t,e,{cwd:n,env:r,stdio:[{string:i},`pipe`,`ignore`]}).then(({stdout:e})=>{if(Buffer.byteLength(e)>10*1024*1024)throw Error(`Translation generator output exceeded 10 MiB.`);return e}).catch(()=>{throw Error(`Translation generator exited unsuccessfully.`)})}function C({compileMessage:e,id:t,locale:n,source:r,translation:i}){let a,o;try{a=e.compileMessageOrThrow(r),o=e.compileMessageOrThrow(i)}catch{throw Error(`Translation ${n}:${t} is not valid ICU MessageFormat.`)}let s=w(a),c=w(o);if(s.length!==c.length||s.some((e,t)=>e!==c[t]))throw Error(`Translation ${n}:${t} does not preserve source ICU placeholders.`)}function w(e){let t=[];function n(e){for(let r of e){if(typeof r==`string`)continue;let[e,i=`argument`,a]=r;if(t.push(`${e}:${i}`),a&&typeof a==`object`&&!Array.isArray(a))for(let e of Object.values(a))Array.isArray(e)&&n(e)}}return n(e),t.sort()}function T(e){return`${e.locale}\0${e.catalog}\0${e.id}`}export{_ as applyGeneratedTranslations,v as assertCompleteCatalogs,d as catalogRelativePath,h as collectMissingTranslations,g as generateMissingTranslations,y as readRichCatalog,p as runLinguiExtract,m as validateLinguiCompile,b as writeRichCatalog};
|
package/dist/i18n/contracts.d.ts
CHANGED
package/dist/i18n/storage.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{assertRevision as e,assertSha256 as t,i18nCommitReferenceKey as n,i18nObjectKey as r,i18nReleaseReferenceKey as i}from"./paths.js";import{createHash as a,randomUUID as o}from"node:crypto";import{copyFile as s,mkdir as c,readFile as l,rename as u,rm as d,stat as f,writeFile as p}from"node:fs/promises";import{dirname as m,join as h,resolve as g}from"node:path";function _(e){return a(`sha256`).update(e).digest(`hex`)}async function v(e){return _(await l(e))}function y(e){return Buffer.from(`${JSON.stringify(e,null,2)}\n`)}async function b({bucket:e,digest:n,projectId:i,source:a,store:s}){if(t(n),await v(a)!==n)throw Error(`I18n object source does not match declared SHA-256 digest ${n}.`);let c=r(i,n);await s.has(e,c)||await s.upload(e,c,a,`application/octet-stream`);let l=`${a}.${process.pid}.${o()}.verify`;try{if(await s.download(e,c,l),await v(l)!==n)throw Error(`Existing immutable i18n object ${c} failed integrity verification.`)}finally{await d(l,{force:!0})}}async function x({bucket:e,key:t,reference:n,store:r,temporaryDirectory:i}){let a=y(n),s=h(i,`reference-${o()}.json`);if(await r.has(e,t))try{if(await r.download(e,t,s),!(await l(s)).equals(a))throw Error(`Immutable i18n reference ${t} already resolves to different snapshot data.`);return}finally{await d(s,{force:!0})}await p(s,a,{flag:`wx`});try{await r.upload(e,t,s,`application/json`)}finally{await d(s,{force:!0})}let c=h(i,`reference-${o()}.verify.json`);try{if(await r.download(e,t,c),!(await l(c)).equals(a))throw Error(`Uploaded immutable i18n reference ${t} failed verification.`)}finally{await d(c,{force:!0})}}async function S({bucket:e,manifest:t,projectId:n,store:r,temporaryDirectory:i}){let a=y(t),o=_(a),s=h(i,`manifest-${o}.json`);await p(s,a,{flag:`wx`});try{await b({bucket:e,digest:o,projectId:n,source:s,store:r})}finally{await d(s,{force:!0})}return o}async function C({bucket:n,key:r,store:i,temporaryDirectory:a}){if(!await i.has(n,r))return;let s=h(a,`reference-${o()}.json`);try{await i.download(n,r,s);let a=JSON.parse(await l(s,`utf8`));if(a.version!==1||typeof a.revision!=`string`||typeof a.snapshot!=`string`)throw Error(`Invalid i18n reference at ${r}.`);return e(a.revision),t(a.snapshot),a}finally{await d(s,{force:!0})}}async function w({bucket:e,projectId:t,revision:r,store:i,temporaryDirectory:a}){let o=await C({bucket:e,key:n(t,r),store:i,temporaryDirectory:a});if(o&&o.revision!==r)throw Error(`I18n commit reference does not match requested revision ${r}.`);return o}async function T({bucket:e,projectId:t,reference:r,store:a,tag:o,temporaryDirectory:s}){await x({bucket:e,key:n(t,r.revision),reference:r,store:a,temporaryDirectory:s}),o&&await x({bucket:e,key:i(t,o),reference:r,store:a,temporaryDirectory:s})}async function E({bucket:e,cacheRoot:n,digest:i,projectId:a,store:l,target:f}){t(i);let p=h(g(n),`v1`,`sha256`,i.slice(0,2),i);if(await O(p,i)===!1){await c(m(p),{recursive:!0});let t=`${p}.${process.pid}.${o()}.tmp`;try{if(await l.download(e,r(a,i),t),await v(t)!==i)throw Error(`Downloaded i18n object failed SHA-256 verification: ${i}.`);await d(p,{force:!0}),await u(t,p)}finally{await d(t,{force:!0})}}await c(m(f),{recursive:!0});let _=`${f}.${process.pid}.${o()}.tmp`;try{if(await s(p,_),await v(_)!==i)throw Error(`Cached i18n object failed SHA-256 verification: ${i}.`);await d(f,{force:!0}),await u(_,f)}finally{await d(_,{force:!0})}}async function D({bucket:n,cacheRoot:r,digest:i,projectId:a,store:o,temporaryDirectory:s}){let c=h(s,`manifest-${i}.json`);await E({bucket:n,cacheRoot:r,digest:i,projectId:a,store:o,target:c});let u=JSON.parse(await l(c,`utf8`));if(u.version!==1||u.projectId!==a||typeof u.revision!=`string`||!Array.isArray(u.files)||!Array.isArray(u.catalogs)||u.catalogs.some(e=>typeof e!=`string`)||!Array.isArray(u.locales)||u.locales.some(e=>typeof e!=`string`)||typeof u.sourceLocale!=`string`||typeof u.generator!=`string`||typeof u.linguiVersion!=`string`)throw Error(`Invalid i18n snapshot manifest ${i}.`);e(u.revision),u.baseline!==void 0&&t(u.baseline);for(let e of u.files){if(!e||typeof e!=`object`||typeof e.path!=`string`||typeof e.digest!=`string`||typeof e.size!=`number
|
|
1
|
+
import{assertRevision as e,assertSha256 as t,i18nCommitReferenceKey as n,i18nObjectKey as r,i18nReleaseReferenceKey as i}from"./paths.js";import{createHash as a,randomUUID as o}from"node:crypto";import{copyFile as s,mkdir as c,readFile as l,rename as u,rm as d,stat as f,writeFile as p}from"node:fs/promises";import{dirname as m,join as h,resolve as g}from"node:path";function _(e){return a(`sha256`).update(e).digest(`hex`)}async function v(e){return _(await l(e))}function y(e){return Buffer.from(`${JSON.stringify(e,null,2)}\n`)}async function b({bucket:e,digest:n,projectId:i,source:a,store:s}){if(t(n),await v(a)!==n)throw Error(`I18n object source does not match declared SHA-256 digest ${n}.`);let c=r(i,n);await s.has(e,c)||await s.upload(e,c,a,`application/octet-stream`);let l=`${a}.${process.pid}.${o()}.verify`;try{if(await s.download(e,c,l),await v(l)!==n)throw Error(`Existing immutable i18n object ${c} failed integrity verification.`)}finally{await d(l,{force:!0})}}async function x({bucket:e,key:t,reference:n,store:r,temporaryDirectory:i}){let a=y(n),s=h(i,`reference-${o()}.json`);if(await r.has(e,t))try{if(await r.download(e,t,s),!(await l(s)).equals(a))throw Error(`Immutable i18n reference ${t} already resolves to different snapshot data.`);return}finally{await d(s,{force:!0})}await p(s,a,{flag:`wx`});try{await r.upload(e,t,s,`application/json`)}finally{await d(s,{force:!0})}let c=h(i,`reference-${o()}.verify.json`);try{if(await r.download(e,t,c),!(await l(c)).equals(a))throw Error(`Uploaded immutable i18n reference ${t} failed verification.`)}finally{await d(c,{force:!0})}}async function S({bucket:e,manifest:t,projectId:n,store:r,temporaryDirectory:i}){let a=y(t),o=_(a),s=h(i,`manifest-${o}.json`);await p(s,a,{flag:`wx`});try{await b({bucket:e,digest:o,projectId:n,source:s,store:r})}finally{await d(s,{force:!0})}return o}async function C({bucket:n,key:r,store:i,temporaryDirectory:a}){if(!await i.has(n,r))return;let s=h(a,`reference-${o()}.json`);try{await i.download(n,r,s);let a=JSON.parse(await l(s,`utf8`));if(a.version!==1||typeof a.revision!=`string`||typeof a.snapshot!=`string`)throw Error(`Invalid i18n reference at ${r}.`);return e(a.revision),t(a.snapshot),a}finally{await d(s,{force:!0})}}async function w({bucket:e,projectId:t,revision:r,store:i,temporaryDirectory:a}){let o=await C({bucket:e,key:n(t,r),store:i,temporaryDirectory:a});if(o&&o.revision!==r)throw Error(`I18n commit reference does not match requested revision ${r}.`);return o}async function T({bucket:e,projectId:t,reference:r,store:a,tag:o,temporaryDirectory:s}){await x({bucket:e,key:n(t,r.revision),reference:r,store:a,temporaryDirectory:s}),o&&await x({bucket:e,key:i(t,o),reference:r,store:a,temporaryDirectory:s})}async function E({bucket:e,cacheRoot:n,digest:i,projectId:a,store:l,target:f}){t(i);let p=h(g(n),`v1`,`sha256`,i.slice(0,2),i);if(await O(p,i)===!1){await c(m(p),{recursive:!0});let t=`${p}.${process.pid}.${o()}.tmp`;try{if(await l.download(e,r(a,i),t),await v(t)!==i)throw Error(`Downloaded i18n object failed SHA-256 verification: ${i}.`);await d(p,{force:!0}),await u(t,p)}finally{await d(t,{force:!0})}}await c(m(f),{recursive:!0});let _=`${f}.${process.pid}.${o()}.tmp`;try{if(await s(p,_),await v(_)!==i)throw Error(`Cached i18n object failed SHA-256 verification: ${i}.`);await d(f,{force:!0}),await u(_,f)}finally{await d(_,{force:!0})}}async function D({bucket:n,cacheRoot:r,digest:i,projectId:a,store:o,temporaryDirectory:s}){let c=h(s,`manifest-${i}.json`);await E({bucket:n,cacheRoot:r,digest:i,projectId:a,store:o,target:c});let u=JSON.parse(await l(c,`utf8`));if(u.version!==1||u.projectId!==a||typeof u.revision!=`string`||!Array.isArray(u.files)||!Array.isArray(u.catalogs)||u.catalogs.some(e=>typeof e!=`string`)||!Array.isArray(u.locales)||u.locales.some(e=>typeof e!=`string`)||typeof u.sourceLocale!=`string`||typeof u.generator!=`string`||typeof u.linguiVersion!=`string`)throw Error(`Invalid i18n snapshot manifest ${i}.`);e(u.revision),u.baseline!==void 0&&t(u.baseline);for(let e of u.files){if(!e||typeof e!=`object`||typeof e.path!=`string`||typeof e.digest!=`string`||typeof e.size!=`number`)throw Error(`Invalid file entry in i18n snapshot manifest ${i}.`);t(e.digest)}return u}async function O(e,t){try{return(await f(e)).isFile()&&await v(e)===t}catch{return!1}}export{b as ensureImmutableObject,x as ensureImmutableReference,E as materializeObject,S as publishSnapshotManifest,w as readCommitReference,D as readSnapshotManifest,C as readSnapshotReference,y as serializeJson,_ as sha256,v as sha256File,T as writeSnapshotReferences};
|
package/dist/i18n/workflows.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I18nConfig } from "../config.js";
|
|
1
|
+
import { CoreframeConfig, I18nConfig } from "../config.js";
|
|
2
2
|
import { PrivateObjectStore } from "../private-object-store.js";
|
|
3
3
|
import { ResolvedI18nConfig } from "./catalogs.js";
|
|
4
4
|
|
|
@@ -12,6 +12,13 @@ declare function buildI18n({
|
|
|
12
12
|
cwd,
|
|
13
13
|
env
|
|
14
14
|
}?: Pick<WorkflowOptions, "cwd" | "env">): Promise<void>;
|
|
15
|
+
declare function ensureDevI18nCatalogs({
|
|
16
|
+
cwd,
|
|
17
|
+
projectConfig
|
|
18
|
+
}?: {
|
|
19
|
+
cwd?: string;
|
|
20
|
+
projectConfig?: CoreframeConfig;
|
|
21
|
+
}): Promise<void>;
|
|
15
22
|
declare function prepareI18nRelease({
|
|
16
23
|
cwd,
|
|
17
24
|
env,
|
|
@@ -36,4 +43,4 @@ declare function materializeI18nSnapshot({
|
|
|
36
43
|
} | undefined>;
|
|
37
44
|
declare function resolveI18nConfig(config: I18nConfig): ResolvedI18nConfig;
|
|
38
45
|
//#endregion
|
|
39
|
-
export { buildI18n, materializeI18nSnapshot, prepareI18nRelease, resolveI18nConfig };
|
|
46
|
+
export { buildI18n, ensureDevI18nCatalogs, materializeI18nSnapshot, prepareI18nRelease, resolveI18nConfig };
|
package/dist/i18n/workflows.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readProjectConfig as e}from"../config.js";import{createB2PrivateObjectStore as t}from"../private-object-store.js";import{importProjectDependency as n}from"../project.js";import{assertI18nSegment as r,assertReleaseTag as i,assertRevision as a,resolveProjectArtifact as o}from"./paths.js";import{applyGeneratedTranslations as s,assertCompleteCatalogs as c,catalogRelativePath as l,collectMissingTranslations as u,
|
|
1
|
+
import{readProjectConfig as e}from"../config.js";import{createB2PrivateObjectStore as t}from"../private-object-store.js";import{importProjectDependency as n}from"../project.js";import{assertI18nSegment as r,assertReleaseTag as i,assertRevision as a,resolveProjectArtifact as o}from"./paths.js";import{applyGeneratedTranslations as s,assertCompleteCatalogs as c,catalogRelativePath as l,collectMissingTranslations as u,generateMissingTranslations as d,runLinguiExtract as f,validateLinguiCompile as p,writeRichCatalog as m}from"./catalogs.js";import{ensureImmutableObject as h,materializeObject as g,publishSnapshotManifest as _,readCommitReference as v,readSnapshotManifest as y,sha256File as b,writeSnapshotReferences as x}from"./storage.js";import{access as S,mkdir as C,mkdtemp as w,rename as T,rm as E,stat as D}from"node:fs/promises";import{dirname as O,join as k,resolve as A}from"node:path";import j from"nano-spawn";import{tmpdir as M}from"node:os";async function N({cwd:t=process.cwd(),env:n=process.env}={}){if((await e({cwd:t})).i18n){if(n.COREFRAME_I18N_RELEASE_REVISION){await I({cwd:t,env:n,revision:n.COREFRAME_I18N_RELEASE_REVISION});return}await f(t)}}async function P({cwd:t=process.cwd(),projectConfig:n}={}){let r=n??await e({cwd:t});if(!r.i18n)return;let i=o(t,L(r.i18n).directory);try{if(!(await D(i)).isDirectory())throw Error(`I18n catalog path is not a directory: ${i}.`);return}catch(e){if(e.code!==`ENOENT`)throw e}await f(t)}async function F({cwd:e=process.cwd(),env:t=process.env,store:n,tag:r}){i(r);let a=await R({cwd:e,env:t,store:n});await K(e);let o=await G(e);await q(e,r,o);let l=await w(k(M(),`coreframe-i18n-prepare-`));try{let n=await v({bucket:a.assets.sourceBucket,projectId:a.assets.projectId,revision:o,store:a.store,temporaryDirectory:l});if(n){let e=await y({bucket:a.assets.sourceBucket,cacheRoot:a.cacheRoot,digest:n.snapshot,projectId:a.assets.projectId,store:a.store,temporaryDirectory:l});return W(a,e,o),await B(a,e),await x({bucket:a.assets.sourceBucket,projectId:a.assets.projectId,reference:n,store:a.store,tag:r,temporaryDirectory:l}),{reused:!0,snapshot:n.snapshot}}return await U(a,l,async()=>{let n=await z(a,o,l);n||await H(a),await f(e);let i=await u({config:a.config,cwd:e}),m=await d({config:a.config,cwd:e,env:t,messages:i});await s({config:a.config,cwd:e,missing:i,response:m}),await c({config:a.config,cwd:e}),await p({config:a.config,cwd:e,strict:!0,temporaryDirectory:l});let h=await V(a),g={...n?{baseline:n}:{},catalogs:a.config.catalogs,files:h,generator:i.length>0?a.config.generator?.id??`unconfigured`:`none`,linguiVersion:await J(e),locales:a.config.locales,projectId:a.assets.projectId,revision:o,sourceLocale:a.config.sourceLocale,version:1},v=await _({bucket:a.assets.sourceBucket,manifest:g,projectId:a.assets.projectId,store:a.store,temporaryDirectory:l});return await x({bucket:a.assets.sourceBucket,projectId:a.assets.projectId,reference:{revision:o,snapshot:v,version:1},store:a.store,tag:r,temporaryDirectory:l}),{reused:!1,snapshot:v}})}finally{await E(l,{force:!0,recursive:!0})}}async function I({cwd:t=process.cwd(),env:n=process.env,revision:r,store:i}={}){let o=await e({cwd:t});if(!o.i18n)return;let s=await R({cwd:t,env:n,store:i,projectConfig:o}),c=a(r??await G(t)),l=await w(k(M(),`coreframe-i18n-materialize-`));try{let e=await v({bucket:s.assets.sourceBucket,projectId:s.assets.projectId,revision:c,store:s.store,temporaryDirectory:l});if(!e)throw Error(`No prepared i18n snapshot exists for commit ${c}. Push a v* tag for this commit and wait for the translation gate.`);let t=await y({bucket:s.assets.sourceBucket,cacheRoot:s.cacheRoot,digest:e.snapshot,projectId:s.assets.projectId,store:s.store,temporaryDirectory:l});return W(s,t,c),await B(s,t),{revision:c,snapshot:e.snapshot}}finally{await E(l,{force:!0,recursive:!0})}}function L(e){let t=r(e.sourceLocale,`Source locale`),n=[...new Set(e.locales.map(e=>r(e,`Locale`)))],i=[...new Set(e.catalogs.map(e=>r(e,`Catalog`)))];if(n.length===0||!n.includes(t))throw Error(`I18n locales must include the source locale.`);if(i.length===0)throw Error(`I18n configuration requires at least one catalog.`);if(e.generator&&(!e.generator.command.trim()||!e.generator.id.trim()))throw Error(`I18n generator command and ID must be non-empty.`);return{catalogs:i,directory:e.directory??`locales`,generator:e.generator,locales:n,sourceLocale:t}}async function R({cwd:n=process.cwd(),env:r=process.env,projectConfig:i,store:a}){let o=i??await e({cwd:n});if(!o.i18n)throw Error(`Missing i18n configuration in coreframe.config.ts.`);if(!o.assets)throw Error(`I18n snapshots require the existing private build bucket configured under assets.`);let s=o.assets;return{assets:s,cacheRoot:A(n,`.coreframe`,`i18n`,`cache`),config:L(o.i18n),cwd:A(n),env:r,store:a??t({config:s,env:r})}}async function z(e,t,n){let{stdout:r}=await j(`git`,[`rev-list`,`--first-parent`,`--skip=1`,t],{cwd:e.cwd,stdin:`ignore`});for(let t of r.split(/\r?\n/).filter(Boolean)){let r=await v({bucket:e.assets.sourceBucket,projectId:e.assets.projectId,revision:a(t),store:e.store,temporaryDirectory:n});if(!r)continue;let i=await y({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:r.snapshot,projectId:e.assets.projectId,store:e.store,temporaryDirectory:n});return W(e,i,t),await B(e,i),r.snapshot}}async function B(e,t){for(let n of t.files)if(await g({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:n.digest,projectId:e.assets.projectId,store:e.store,target:o(e.cwd,n.path)}),(await D(o(e.cwd,n.path))).size!==n.size)throw Error(`Materialized i18n artifact size does not match manifest: ${n.path}.`)}async function V(e){let t=[];for(let n of e.config.locales)for(let r of e.config.catalogs){let i=l(e.config,n,r),a=o(e.cwd,i),s=await b(a);await h({bucket:e.assets.sourceBucket,digest:s,projectId:e.assets.projectId,source:a,store:e.store}),t.push({digest:s,path:i,size:(await D(a)).size})}return t.sort((e,t)=>e.path.localeCompare(t.path))}async function H(e){let{stdout:t}=await j(`git`,[`rev-parse`,`--show-prefix`],{cwd:e.cwd,stdin:`ignore`}),r=t.trim(),{stdout:i}=await j(`git`,[`log`,`-1`,`--format=%H`,`--diff-filter=AM`,`--`,`:(top)${`${r}${e.config.directory}/${e.config.sourceLocale}/${e.config.catalogs[0]}.po`}`],{cwd:e.cwd,stdin:`ignore`}),a=i.trim();if(!a)return!1;let s=(await n(`@lingui/format-po`,e.cwd)).formatter({lineNumbers:!1}),c=!1;for(let t of e.config.locales)for(let n of e.config.catalogs){let i=`${r}${`${e.config.directory}/${t}/${n}.po`}`;try{let{stdout:r}=await j(`git`,[`show`,`${a}:${i}`],{cwd:e.cwd,stdin:`ignore`});await m(o(e.cwd,l(e.config,t,n)),s.parse(r)),c=!0}catch{}}return c}async function U(e,t,n){let r=[];for(let n of e.config.locales)for(let i of e.config.catalogs){let a=l(e.config,n,i),s=o(e.cwd,a);try{await S(s)}catch{continue}let c=k(t,`previous-catalogs`,a);await C(O(c),{recursive:!0}),await T(s,c),r.push({backup:c,path:s})}try{let e=await n();return await E(k(t,`previous-catalogs`),{force:!0,recursive:!0}),e}catch(t){for(let t of e.config.locales)for(let n of e.config.catalogs)await E(o(e.cwd,l(e.config,t,n)),{force:!0});for(let{backup:e,path:t}of r)await C(O(t),{recursive:!0}),await T(e,t);throw t}}function W(e,t,n){if(t.revision!==n||t.projectId!==e.assets.projectId||t.sourceLocale!==e.config.sourceLocale||JSON.stringify(t.locales)!==JSON.stringify(e.config.locales)||JSON.stringify(t.catalogs)!==JSON.stringify(e.config.catalogs))throw Error(`I18n snapshot does not match commit or project configuration.`);let r=e.config.locales.flatMap(t=>e.config.catalogs.map(n=>l(e.config,t,n))),i=t.files.map(e=>e.path);if(new Set(i).size!==i.length||JSON.stringify(i.sort())!==JSON.stringify(r.sort()))throw Error(`I18n snapshot has an incomplete or unexpected artifact set.`)}async function G(e){let{stdout:t}=await j(`git`,[`rev-parse`,`HEAD`],{cwd:e,stdin:`ignore`});return a(t.trim())}async function K(e){let{stdout:t}=await j(`git`,[`status`,`--porcelain`],{cwd:e,stdin:`ignore`});if(t.trim())throw Error(`Tagged i18n preparation requires a clean Git tree.`)}async function q(e,t,n){let{stdout:r}=await j(`git`,[`rev-parse`,`${t}^{commit}`],{cwd:e,stdin:`ignore`});if(r.trim()!==n)throw Error(`Release tag ${t} does not point to checked-out commit ${n}.`)}async function J(e){let{stdout:t}=await j(`pnpm`,[`exec`,`lingui`,`--version`],{cwd:e,stdin:`ignore`});return t.trim()}export{N as buildI18n,P as ensureDevI18nCatalogs,I as materializeI18nSnapshot,F as prepareI18nRelease,L as resolveI18nConfig};
|
package/dist/managed-dev.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ type ManagedDevSessionOptions = {
|
|
|
7
7
|
config: CoreframeConfig;
|
|
8
8
|
cwd?: string;
|
|
9
9
|
env?: NodeJS.ProcessEnv;
|
|
10
|
+
localCheckInterval?: number;
|
|
10
11
|
onRestart?(): void;
|
|
11
12
|
onStatusChange?(status: ManagedDevStatus): void;
|
|
12
13
|
remoteCheckInterval?: number;
|
|
@@ -36,6 +37,7 @@ declare function startManagedDevSession({
|
|
|
36
37
|
config,
|
|
37
38
|
cwd,
|
|
38
39
|
env,
|
|
40
|
+
localCheckInterval,
|
|
39
41
|
onRestart,
|
|
40
42
|
onStatusChange,
|
|
41
43
|
remoteCheckInterval,
|
package/dist/managed-dev.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{createHash as e,randomBytes as t}from"node:crypto";import{access as n,copyFile as r,mkdir as i,mkdtemp as a,open as o,readFile as s,realpath as c,rm as l,unlink as u,writeFile as d}from"node:fs/promises";import f from"node:path";import p,{SubprocessError as m}from"nano-spawn";import{pathToFileURL as h}from"node:url";import{constants as g,watch as _}from"node:fs";import v from"node:process";import{resolve as y}from"import-meta-resolve";const b=`refs/heads/main`,x=`refs/heads/dev`,ee=`refs/remotes/origin/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i,S=`coreframe-managed-dev-codex-completion.json`,ne=`coreframe-managed-dev-setup-failure.json`;async function C(e=v.cwd()){let t=await se(e);return t.primary&&t.branch===`main`&&t.head===t.main}async function w(e=v.cwd()){try{let{commonDir:t,gitDir:n}=await T(e);return n===t}catch{return!1}}async function T(e){let t=await c(await Y(e,[`rev-parse`,`--show-toplevel`])),n=await c(e),r=f.resolve(n,await Y(e,[`rev-parse`,`--git-dir`])),i=f.resolve(n,await Y(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function E({config:e,cwd:n=v.cwd(),env:r=v.env,onRestart:i=()=>void 0,onStatusChange:a=()=>void 0,remoteCheckInterval:o=6e4,runCheck:s=e=>pe(n,r,e),watchState:c=ce}){let l=r,m={mode:`waiting`,warnings:[]},h=!1,g=!1,_=!1,y=!1,C,w,T,E,D,ie=[],O,k,A=Promise.resolve(),N=()=>{h||a(m)},P=async({fetch:e=!1}={})=>{if(!(!g||h||!w)){if(_){y=!0;return}try{let[t,r,i]=await Promise.all([Y(n,[`rev-parse`,`--abbrev-ref`,`HEAD`]),Y(n,[`rev-parse`,`HEAD`]),Y(n,[`rev-parse`,b])]);if(t!==`main`||r!==i){m={message:`Managed synchronization is paused until the primary checkout is back on local main.`,mode:`waiting`,warnings:[]};return}r!==C&&(C=r,O=void 0);let a=await j(n);if(a.tracked||a.untracked.length>0){m={...m,currentCommit:C,draft:a,message:void 0,mode:`managed`,proposal:B(a.fingerprint),target:void 0};return}e&&await X(n,[`remote`,`get-url`,`origin`])&&await J(n,[`fetch`,`origin`,`+refs/heads/main:${ee}`]);let o=await X(n,[`rev-parse`,x]),s=await X(n,[`rev-parse`,ee]),c=[...o?[{commit:o,source:`dev`}]:[],...s?[{commit:s,source:`upstream`}]:[]],l;for(let e of c)if(!await Se(n,e.commit,C)){l=e;break}m={...m,currentCommit:C,draft:void 0,message:void 0,mode:`managed`,proposal:void 0,target:l===void 0?void 0:await ye(n,l.commit,l.source)}}catch(e){m={...m,message:Q(e),warnings:[Q(e)]}}finally{N()}}},F=()=>{clearTimeout(D),D=setTimeout(()=>void P(),50),D.unref()},I=(e,n)=>{let r=async()=>{let r=[{command:`pnpm typecheck`,status:`running`},{command:`pnpm test`,status:`pending`}],i=()=>{m={...m,checks:{commit:e,commands:structuredClone(r),trigger:n}},N()};i();for(let[e,n]of[`typecheck`,`test`].entries()){e>0&&(r[e].status=`running`,i());try{await s(n),r[e].status=`passed`}catch(n){r[e].status=`failed`,r[e].failureId=t(12).toString(`hex`),r[e].output=me(n)}i()}};A=A.then(r,r)},L=async()=>{if(g||h)return;let e=await se(n);if(!e.primary){m={message:`Managed development only runs from the primary checkout.`,mode:`unmanaged`,warnings:[]},N();return}if(e.branch!==`main`||e.head!==e.main){let t=`Managed development requires the primary checkout on local main; current branch is ${e.branch??`detached HEAD`}.`;console.warn(`Coreframe managed development disabled: ${t}`),m={message:t,mode:`unmanaged`,warnings:[]},N();return}T=f.join(e.commonDir,`coreframe-managed-dev.lock`),await be(T),await X(n,[`rev-parse`,`--verify`,x])||await J(n,[`branch`,`dev`,e.head]),w=e,C=e.head,g=!0,m={codexCompletion:await re(e.commonDir),currentCommit:e.head,mode:`managed`,setupFailure:await oe(e.commonDir,e.head),warnings:[]},N(),ie=await c(e,F),E=setInterval(()=>void P({fetch:!0}),o),E.unref(),await P(),P({fetch:!0})},R=async(e,{onCodexEvent:t=()=>void 0}={})=>{if(!g||m.mode!==`managed`)throw Error(`Managed development is not active.`);if(_)throw Error(`Another managed development action is already running.`);let r=[],i=[],a,o=e=>{e.phase===`start`?(i=e.commits,r.splice(0,r.length,e.message)):e.phase===`message`?r.push(e.message):e.phase===`complete`?a=e.finalMessage:e.phase===`progress`&&(i=e.commits),t(e)};_=!0,m={...m,busy:Te(e),message:void 0},N();try{if(e.type===`acknowledge-codex`)m.codexCompletion?.id===e.id&&await Ae();else if(e.type===`dismiss-check`)m.checks&&(m={...m,checks:{...m.checks,commands:m.checks.commands.map(t=>t.failureId===e.failureId?{...t,dismissed:!0}:t)}});else if(e.type===`reject`)m={...m,draft:void 0,proposal:void 0};else if(e.type===`prepare`){let t=z(e.target),r=await j(n);r.tracked||r.untracked.length>0?m={...m,draft:r,proposal:B(r.fingerprint)}:await H({onCodexEvent:o,source:t.source,target:e.target})}else if(e.type===`message`){let t=await V(e.fingerprint,e.untracked),r=B(t.fingerprint);if(r===void 0){try{if(k??=ue(`codex`,l),!await k)throw Error("Codex CLI is not installed or is unavailable on PATH. Install it with `npm install -g @openai/codex`, then restart the dev server.");r=await le(n,l,t.untracked)}catch(e){r=``,m={...m,warnings:[...m.warnings,`Codex could not generate a commit message: ${Q(e)}`]}}O={fingerprint:t.fingerprint,message:r}}m={...m,draft:t,proposal:r}}else if(e.type===`commit`){let t=await ge(e);m={...m,currentCommit:t,draft:void 0,message:void 0,proposal:void 0,target:void 0},F()}else if(e.type===`retry-install`)await W();else if(e.type===`reset-database`)await G();else{let t=z(e.target),r=await j(n);if(r.tracked||r.untracked.length>0){if(!e.fingerprint||!e.untracked)throw Error(`Refresh requires the current working-tree confirmation.`);if(await V(e.fingerprint,e.untracked),!e.message||!te.test(we(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await H({fingerprint:e.fingerprint,message:e.message,onCodexEvent:o,source:t.source,target:e.target,untracked:e.untracked})}}finally{_=!1,m={...m,busy:void 0},N(),y&&(y=!1,F())}return a&&await ke(a,r,i),{status:m}},z=e=>{if(!m.target||m.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`);return m.target},B=e=>O?.fingerprint===e?O.message:void 0,V=async(e,t)=>{let r=await j(n);if(r.fingerprint!==e)throw O=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!Ce(r.untracked,t))throw Error(`Include every untracked file or remove it before refreshing.`);return r},ge=async({fingerprint:e,message:t,untracked:r})=>{let i=await V(e,r);if(!t||!te.test(we(t)))throw Error(`Enter a commit message with a valid Conventional Commits header.`);await J(n,[`add`,`--update`]),i.untracked.length>0&&await J(n,[`add`,`--`,...r]),await J(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}});let a=await Y(n,[`rev-parse`,`HEAD`]);return C=a,O=void 0,a},H=async({fingerprint:e,message:t,onCodexEvent:r=()=>void 0,source:i,target:a,untracked:o=[]})=>{z(a);let s=await Y(n,[`rev-parse`,`HEAD`]),c,u,d=await j(n);if(d.tracked||d.untracked.length>0){if(!e||d.fingerprint!==e||!Ce(d.untracked,o))throw Error(`Working-tree changes changed; review them before refreshing.`);await J(n,[`add`,`--update`]),o.length>0&&await J(n,[`add`,`--`,...o]),await J(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}}),c=await Y(n,[`rev-parse`,`HEAD`]),C=c,u=`refs/coreframe/recovery/${Date.now()}-${c.slice(0,12)}`,await J(n,[`update-ref`,u,c])}let f=c??s,p;try{if(p=await de({cwd:n,env:l,localMain:f,onCodexEvent:r,source:i,target:a}),await Y(n,[`rev-parse`,`HEAD`])!==f)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await Y(n,[`rev-parse`,b])!==f)throw Error(`Local main changed while the accepted update was being prepared.`);await fe(n,p,f),C=p.commit,await J(n,[`reset`,`--hard`,p.commit]);let e=Z(await Y(n,[`diff`,`--name-only`,`-z`,s,p.commit]));O=void 0,u&&await J(n,[`update-ref`,`-d`,u]),m={...m,currentCommit:p.commit,draft:void 0,proposal:void 0,setupFailure:void 0,target:void 0},await U({installDependencies:_e(e),restartRequired:ve(e),trigger:`synchronization`})}catch(e){e instanceof M&&(y=!0);let t=u?` Recovery commit: ${u}.`:``;throw m={...m,currentCommit:C,message:`${Q(e)}${t}`},e}},U=async({installDependencies:t,restartRequired:r,trigger:a})=>{let o=C;if(t)try{await q([`install`,`--frozen-lockfile`])}catch(e){await De({command:`pnpm install --frozen-lockfile`,commit:o,error:e,message:`The project was synchronized, but dependency installation failed. Fix the package or lockfile issue, then retry the install.`,restartRequired:r,stage:`dependencies`});return}try{await he({config:e,cwd:n,env:l})}catch(e){await De({command:`pnpm db migrate`,commit:o,error:e,message:`The project was synchronized, but its database migration failed. The previous database was restored. Reset the database to recreate it, apply migrations, and rerun seed scripts.`,restartRequired:r,stage:`migration`});return}await $(),I(o,a),r&&i()},W=async()=>{let e=K(`dependencies`);await $(),await U({installDependencies:!0,restartRequired:e.restartRequired,trigger:`dependency-recovery`})},G=async()=>{let e=K(`migration`);try{await q([`db`,`setup`])}catch(t){await De({command:`pnpm db setup`,commit:e.commit,error:t,message:`The project remains synchronized, but the database reset failed. Review the diagnostics, fix the reported problem, and try the reset again.`,restartRequired:e.restartRequired,stage:`migration`});return}await $(),I(e.commit,`database-recovery`),e.restartRequired&&i()},K=e=>{if(!m.setupFailure||m.setupFailure.stage!==e)throw Error(`There is no failed ${e} setup step to recover.`);return m.setupFailure},q=async e=>{await p(Ee(),e,{cwd:n,env:l})},De=async({command:e,commit:t,error:n,message:r,restartRequired:i,stage:a})=>{let o=me(n).slice(-1e5),s={command:e,commit:t,message:r,output:o,restartRequired:i,stage:a};m={...m,setupFailure:s,target:void 0},console.error(`Coreframe managed development setup failed (${e}): ${r}\n${o}`);let c=Oe();c&&await d(c,`${JSON.stringify(s)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development setup failure: ${Q(e)}`)})},$=async()=>{m={...m,setupFailure:void 0};let e=Oe();e&&await u(e).catch(e=>{e instanceof Error&&`code`in e&&e.code===`ENOENT`||console.warn(`Could not clear the managed-development setup failure: ${Q(e)}`)})},Oe=()=>w?f.join(w.commonDir,ne):void 0,ke=async(e,n,r)=>{let i={commits:r,finalMessage:e,id:t(16).toString(`hex`),messages:ae(n)};m={...m,codexCompletion:i},w&&await d(f.join(w.commonDir,S),`${JSON.stringify(i)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex result: ${Q(e)}`)}),N()},Ae=async()=>{m={...m,codexCompletion:void 0},w&&await u(f.join(w.commonDir,S)).catch(e=>{if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e})};return{action:R,activate:L,getStatus:()=>m,async close(){if(!h){h=!0,clearInterval(E),clearTimeout(D);for(let e of ie)e.close();await xe(T)}}}}async function re(e){let t=f.join(e,S);try{let e=JSON.parse(await s(t,`utf8`));if(D(e))return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development Codex result: ${Q(e)}`)}await u(t).catch(()=>void 0)}function D(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.finalMessage==`string`&&typeof t.id==`string`&&Array.isArray(t.messages)&&t.messages.every(O)&&(t.commits===void 0||Array.isArray(t.commits)&&t.commits.every(ie))}function ie(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.commit==`string`&&typeof t.shortCommit==`string`&&typeof t.subject==`string`}function O(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.kind===`agent`||t.kind===`thought`||t.kind===`user`)&&typeof t.text==`string`}function ae(e){let t=new Set(e.filter(e=>e.kind===`user`)),n=[...t].reduce((e,t)=>e+t.text.length,0),r=!1;for(let i of[...e].reverse())if(i.kind!==`user`){if(n+i.text.length>1e5&&r)break;t.add(i),r=!0,n+=i.text.length}return e.filter(e=>t.has(e))}async function oe(e,t){let n=f.join(e,ne);try{let e=JSON.parse(await s(n,`utf8`));if(k(e)&&e.commit===t)return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development setup failure: ${Q(e)}`)}await u(n).catch(()=>void 0)}function k(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.command===`pnpm db migrate`||t.command===`pnpm db setup`||t.command===`pnpm install --frozen-lockfile`)&&typeof t.commit==`string`&&typeof t.message==`string`&&typeof t.output==`string`&&typeof t.restartRequired==`boolean`&&(t.stage===`dependencies`||t.stage===`migration`)}async function se(e){let t=await T(e);return{branch:A(await Y(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await Y(e,[`rev-parse`,`HEAD`]),main:await Y(e,[`rev-parse`,b]),primary:t.primary}}function A(e){return e===`HEAD`?void 0:e}async function ce(e,t){let n=[e.gitDir,f.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(_(e,{persistent:!1},t))}catch{}return r}async function j(t){let[n,r,i]=await Promise.all([Y(t,[`status`,`--porcelain`,`--untracked-files=no`]),Y(t,[`diff`,`HEAD`,`--binary`]),Y(t,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),a=Z(i).sort(),o=e(`sha256`).update(r);for(let e of a)o.update(`\0`).update(e);return{fingerprint:o.digest(`hex`),tracked:n.length>0,untracked:a}}async function le(e,t,n){let r=[`Tracked changes:`,await Y(e,[`diff`,`HEAD`,`--binary`])];for(let t of n){let n=await s(f.join(e,t));r.push(`\nUntracked file: ${t}\n`,n.toString(`utf8`))}let{stdout:i}=await p(`codex`,[`exec`,`--ephemeral`,`--ignore-user-config`,`--sandbox`,`read-only`,`--cd`,e,`Return only a concise Conventional Commits message for the supplied working-tree changes. Use a body only when it adds material context.`],{cwd:e,env:t,stderr:`ignore`,stdin:{string:r.join(`
|
|
2
|
-
`)}});return i.trim().replace(/^```(?:text)?\s*|\s*```$/g,``)}async function
|
|
3
|
-
`)}\n`}})}catch(r){if(t.devTarget)try{let[r,i]=await Promise.all([
|
|
4
|
-
`).trim();throw t?Error(`${
|
|
5
|
-
`).map(e=>{let[t,n=``]=e.split(`\0`,2);return{commit:t,shortCommit:t.slice(0,12),subject:n}}):[]}function
|
|
1
|
+
import{createHash as e,randomBytes as t}from"node:crypto";import{access as n,copyFile as r,mkdir as i,mkdtemp as a,open as o,readFile as s,realpath as c,rm as l,unlink as u,writeFile as d}from"node:fs/promises";import f from"node:path";import p,{SubprocessError as m}from"nano-spawn";import{pathToFileURL as h}from"node:url";import{constants as g,watch as _}from"node:fs";import v from"node:process";import{resolve as y}from"import-meta-resolve";const b=`refs/heads/main`,x=`refs/heads/dev`,ee=`refs/remotes/origin/main`,te=/^[a-z][a-z0-9-]*(?:\([^)]+\))?!?:\s+\S/i,S=`coreframe-managed-dev-codex-completion.json`,ne=`coreframe-managed-dev-setup-failure.json`;async function C(e=v.cwd()){let t=await oe(e);return t.primary&&t.branch===`main`&&t.head===t.main}async function w(e=v.cwd()){try{let{commonDir:t,gitDir:n}=await T(e);return n===t}catch{return!1}}async function T(e){let t=await c(await q(e,[`rev-parse`,`--show-toplevel`])),n=await c(e),r=f.resolve(n,await q(e,[`rev-parse`,`--git-dir`])),i=f.resolve(n,await q(e,[`rev-parse`,`--git-common-dir`]));return{commonDir:i,gitDir:r,primary:t===n&&r===i}}async function E({config:e,cwd:n=v.cwd(),env:r=v.env,localCheckInterval:i=1e3,onRestart:a=()=>void 0,onStatusChange:o=()=>void 0,remoteCheckInterval:s=6e4,runCheck:c=e=>fe(n,r,e),watchState:l=se}){let m=r,h={mode:`waiting`,warnings:[]},g=!1,_=!1,y=!1,C=!1,w,T,E,D,O,k,A=[],j,P,F=Promise.resolve(),I=()=>{g||o(h)},L=async({fetch:e=!1}={})=>{if(!(!_||g||!T)){if(y){C=!0;return}try{let[t,r,i]=await Promise.all([q(n,[`rev-parse`,`--abbrev-ref`,`HEAD`]),q(n,[`rev-parse`,`HEAD`]),q(n,[`rev-parse`,b])]);if(t!==`main`||r!==i){h={message:`Managed synchronization is paused until the primary checkout is back on local main.`,mode:`waiting`,warnings:[]};return}r!==w&&(w=r,j=void 0);let a=await M(n);if(a.tracked||a.untracked.length>0){h={...h,currentCommit:w,draft:a,message:void 0,mode:`managed`,proposal:V(a.fingerprint),target:void 0};return}e&&await J(n,[`remote`,`get-url`,`origin`])&&await K(n,[`fetch`,`origin`,`+refs/heads/main:${ee}`]);let o=await J(n,[`rev-parse`,x]),s=await J(n,[`rev-parse`,ee]),c=[...o?[{commit:o,source:`dev`}]:[],...s?[{commit:s,source:`upstream`}]:[]],l;for(let e of c)if(!await we(n,e.commit,w)){l=e;break}h={...h,currentCommit:w,draft:void 0,message:void 0,mode:`managed`,proposal:void 0,target:l===void 0?void 0:await be(n,l.commit,l.source)}}catch(e){h={...h,message:Z(e),warnings:[Z(e)]}}finally{I()}}},R=()=>{clearTimeout(k),k=setTimeout(()=>void L(),50),k.unref()},z=(e,n)=>{let r=async()=>{let r=[{command:`pnpm typecheck`,status:`running`},{command:`pnpm test`,status:`pending`}],i=()=>{h={...h,checks:{commit:e,commands:structuredClone(r),trigger:n}},I()};i();for(let[e,n]of[`typecheck`,`test`].entries()){e>0&&(r[e].status=`running`,i());try{await c(n),r[e].status=`passed`}catch(n){r[e].status=`failed`,r[e].failureId=t(12).toString(`hex`),r[e].output=pe(n)}i()}};F=F.then(r,r)},he=async()=>{if(_||g)return;let e=await oe(n);if(!e.primary){h={message:`Managed development only runs from the primary checkout.`,mode:`unmanaged`,warnings:[]},I();return}if(e.branch!==`main`||e.head!==e.main){let t=`Managed development requires the primary checkout on local main; current branch is ${e.branch??`detached HEAD`}.`;console.warn(`Coreframe managed development disabled: ${t}`),h={message:t,mode:`unmanaged`,warnings:[]},I();return}E=f.join(e.commonDir,`coreframe-managed-dev.lock`),await xe(E),await J(n,[`rev-parse`,`--verify`,x])||await K(n,[`branch`,`dev`,e.head]),T=e,w=e.head,_=!0,h={codexCompletion:await re(e.commonDir),currentCommit:e.head,mode:`managed`,setupFailure:await ae(e.commonDir,e.head),warnings:[]},I(),A=await l(e,R),D=setInterval(()=>{h.draft&&L()},i),D.unref(),O=setInterval(()=>void L({fetch:!0}),s),O.unref(),await L(),L({fetch:!0})},ge=async(e,{onCodexEvent:t=()=>void 0}={})=>{if(!_||h.mode!==`managed`)throw Error(`Managed development is not active.`);if(y)throw Error(`Another managed development action is already running.`);let r=[],i=[],a,o=e=>{e.phase===`start`?(i=e.commits,r.splice(0,r.length,e.message)):e.phase===`message`?r.push(e.message):e.phase===`complete`?a=e.finalMessage:e.phase===`progress`&&(i=e.commits),t(e)};y=!0,h={...h,busy:De(e),message:void 0},I();try{if(e.type===`acknowledge-codex`)h.codexCompletion?.id===e.id&&await Me();else if(e.type===`dismiss-check`)h.checks&&(h={...h,checks:{...h.checks,commands:h.checks.commands.map(t=>t.failureId===e.failureId?{...t,dismissed:!0}:t)}});else if(e.type===`reject`)h={...h,draft:void 0,proposal:void 0};else if(e.type===`prepare`){let t=B(e.target),r=await M(n);r.tracked||r.untracked.length>0?h={...h,draft:r,proposal:V(r.fingerprint)}:await W({onCodexEvent:o,source:t.source,target:e.target})}else if(e.type===`message`){let t=await H(e.fingerprint,e.untracked),r=V(t.fingerprint);if(r===void 0){try{if(P??=le(`codex`,m),!await P)throw Error("Codex CLI is not installed or is unavailable on PATH. Install it with `npm install -g @openai/codex`, then restart the dev server.");r=await ce(n,m,t.untracked)}catch(e){r=``,h={...h,warnings:[...h.warnings,`Codex could not generate a commit message: ${Z(e)}`]}}j={fingerprint:t.fingerprint,message:r}}h={...h,draft:t,proposal:r}}else if(e.type===`commit`){let t=await U(e);h={...h,currentCommit:t,draft:void 0,message:void 0,proposal:void 0,target:void 0},R()}else if(e.type===`retry-install`)await _e();else if(e.type===`reset-database`)await Se();else{let t=B(e.target),r=await M(n);if(r.tracked||r.untracked.length>0){if(!e.fingerprint||!e.untracked)throw Error(`Refresh requires the current working-tree confirmation.`);if(await H(e.fingerprint,e.untracked),!e.message||!te.test(Ee(e.message)))throw Error(`Enter a commit message with a valid Conventional Commits header.`)}await W({fingerprint:e.fingerprint,message:e.message,onCodexEvent:o,source:t.source,target:e.target,untracked:e.untracked})}}finally{y=!1,h={...h,busy:void 0},I(),C&&(C=!1,R())}return a&&await je(a,r,i),{status:h}},B=e=>{if(!h.target||h.target.commit!==e)throw Error(`The offered update changed. Review the latest target before refreshing.`);return h.target},V=e=>j?.fingerprint===e?j.message:void 0,H=async(e,t)=>{let r=await M(n);if(r.fingerprint!==e)throw j=void 0,Error(`Working-tree changes changed; generate a new commit message.`);if(!Te(r.untracked,t))throw Error(`Include every untracked file or remove it before refreshing.`);return r},U=async({fingerprint:e,message:t,untracked:r})=>{let i=await H(e,r);if(!t||!te.test(Ee(t)))throw Error(`Enter a commit message with a valid Conventional Commits header.`);await K(n,[`add`,`--update`]),i.untracked.length>0&&await K(n,[`add`,`--`,...r]),await K(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}});let a=await q(n,[`rev-parse`,`HEAD`]);return w=a,j=void 0,a},W=async({fingerprint:e,message:t,onCodexEvent:r=()=>void 0,source:i,target:a,untracked:o=[]})=>{B(a);let s=await q(n,[`rev-parse`,`HEAD`]),c,l,u=await M(n);if(u.tracked||u.untracked.length>0){if(!e||u.fingerprint!==e||!Te(u.untracked,o))throw Error(`Working-tree changes changed; review them before refreshing.`);await K(n,[`add`,`--update`]),o.length>0&&await K(n,[`add`,`--`,...o]),await K(n,[`commit`,`--message`,t],{env:{GIT_EDITOR:`true`}}),c=await q(n,[`rev-parse`,`HEAD`]),w=c,l=`refs/coreframe/recovery/${Date.now()}-${c.slice(0,12)}`,await K(n,[`update-ref`,l,c])}let d=c??s,f;try{if(f=await ue({cwd:n,env:m,localMain:d,onCodexEvent:r,source:i,target:a}),await q(n,[`rev-parse`,`HEAD`])!==d)throw Error(`HEAD changed while the accepted update was being prepared.`);if(await q(n,[`rev-parse`,b])!==d)throw Error(`Local main changed while the accepted update was being prepared.`);await de(n,f,d),w=f.commit,await K(n,[`reset`,`--hard`,f.commit]);let e=Y(await q(n,[`diff`,`--name-only`,`-z`,s,f.commit]));j=void 0,l&&await K(n,[`update-ref`,`-d`,l]),h={...h,currentCommit:f.commit,draft:void 0,proposal:void 0,setupFailure:void 0,target:void 0},await G({installDependencies:ve(e),restartRequired:ye(e),trigger:`synchronization`})}catch(e){e instanceof N&&(C=!0);let t=l?` Recovery commit: ${l}.`:``;throw h={...h,currentCommit:w,message:`${Z(e)}${t}`},e}},G=async({installDependencies:t,restartRequired:r,trigger:i})=>{let o=w;if(t)try{await ke([`install`,`--frozen-lockfile`])}catch(e){await Q({command:`pnpm install --frozen-lockfile`,commit:o,error:e,message:`The project was synchronized, but dependency installation failed. Fix the package or lockfile issue, then retry the install.`,restartRequired:r,stage:`dependencies`});return}try{await me({config:e,cwd:n,env:m})}catch(e){await Q({command:`pnpm db migrate`,commit:o,error:e,message:`The project was synchronized, but its database migration failed. The previous database was restored. Reset the database to recreate it, apply migrations, and rerun seed scripts.`,restartRequired:r,stage:`migration`});return}await $(),z(o,i),r&&a()},_e=async()=>{let e=Oe(`dependencies`);await $(),await G({installDependencies:!0,restartRequired:e.restartRequired,trigger:`dependency-recovery`})},Se=async()=>{let e=Oe(`migration`);try{await ke([`db`,`setup`])}catch(t){await Q({command:`pnpm db setup`,commit:e.commit,error:t,message:`The project remains synchronized, but the database reset failed. Review the diagnostics, fix the reported problem, and try the reset again.`,restartRequired:e.restartRequired,stage:`migration`});return}await $(),z(e.commit,`database-recovery`),e.restartRequired&&a()},Oe=e=>{if(!h.setupFailure||h.setupFailure.stage!==e)throw Error(`There is no failed ${e} setup step to recover.`);return h.setupFailure},ke=async e=>{await p(X(),e,{cwd:n,env:m})},Q=async({command:e,commit:t,error:n,message:r,restartRequired:i,stage:a})=>{let o=pe(n).slice(-1e5),s={command:e,commit:t,message:r,output:o,restartRequired:i,stage:a};h={...h,setupFailure:s,target:void 0},console.error(`Coreframe managed development setup failed (${e}): ${r}\n${o}`);let c=Ae();c&&await d(c,`${JSON.stringify(s)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development setup failure: ${Z(e)}`)})},$=async()=>{h={...h,setupFailure:void 0};let e=Ae();e&&await u(e).catch(e=>{e instanceof Error&&`code`in e&&e.code===`ENOENT`||console.warn(`Could not clear the managed-development setup failure: ${Z(e)}`)})},Ae=()=>T?f.join(T.commonDir,ne):void 0,je=async(e,n,r)=>{let i={commits:r,finalMessage:e,id:t(16).toString(`hex`),messages:ie(n)};h={...h,codexCompletion:i},T&&await d(f.join(T.commonDir,S),`${JSON.stringify(i)}\n`,{mode:384}).catch(e=>{console.warn(`Could not persist the managed-development Codex result: ${Z(e)}`)}),I()},Me=async()=>{h={...h,codexCompletion:void 0},T&&await u(f.join(T.commonDir,S)).catch(e=>{if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e})};return{action:ge,activate:he,getStatus:()=>h,async close(){if(!g){g=!0,clearInterval(D),clearInterval(O),clearTimeout(k);for(let e of A)e.close();await Ce(E)}}}}async function re(e){let t=f.join(e,S);try{let e=JSON.parse(await s(t,`utf8`));if(D(e))return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development Codex result: ${Z(e)}`)}await u(t).catch(()=>void 0)}function D(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.finalMessage==`string`&&typeof t.id==`string`&&Array.isArray(t.messages)&&t.messages.every(k)&&(t.commits===void 0||Array.isArray(t.commits)&&t.commits.every(O))}function O(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.commit==`string`&&typeof t.shortCommit==`string`&&typeof t.subject==`string`}function k(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.kind===`agent`||t.kind===`thought`||t.kind===`user`)&&typeof t.text==`string`}function ie(e){let t=new Set(e.filter(e=>e.kind===`user`)),n=[...t].reduce((e,t)=>e+t.text.length,0),r=!1;for(let i of[...e].reverse())if(i.kind!==`user`){if(n+i.text.length>1e5&&r)break;t.add(i),r=!0,n+=i.text.length}return e.filter(e=>t.has(e))}async function ae(e,t){let n=f.join(e,ne);try{let e=JSON.parse(await s(n,`utf8`));if(A(e)&&e.commit===t)return e}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;console.warn(`Could not read the managed-development setup failure: ${Z(e)}`)}await u(n).catch(()=>void 0)}function A(e){if(!e||typeof e!=`object`)return!1;let t=e;return(t.command===`pnpm db migrate`||t.command===`pnpm db setup`||t.command===`pnpm install --frozen-lockfile`)&&typeof t.commit==`string`&&typeof t.message==`string`&&typeof t.output==`string`&&typeof t.restartRequired==`boolean`&&(t.stage===`dependencies`||t.stage===`migration`)}async function oe(e){let t=await T(e);return{branch:j(await q(e,[`rev-parse`,`--abbrev-ref`,`HEAD`])),commonDir:t.commonDir,gitDir:t.gitDir,head:await q(e,[`rev-parse`,`HEAD`]),main:await q(e,[`rev-parse`,b]),primary:t.primary}}function j(e){return e===`HEAD`?void 0:e}async function se(e,t){let n=[e.gitDir,f.join(e.commonDir,`refs`,`heads`)],r=[];for(let e of n)try{r.push(_(e,{persistent:!1},t))}catch{}return r}async function M(t){let[n,r,i]=await Promise.all([q(t,[`status`,`--porcelain`,`--untracked-files=no`]),q(t,[`diff`,`HEAD`,`--binary`]),q(t,[`ls-files`,`--others`,`--exclude-standard`,`-z`])]),a=Y(i).sort(),o=e(`sha256`).update(r);for(let e of a)o.update(`\0`).update(e);return{fingerprint:o.digest(`hex`),tracked:n.length>0,untracked:a}}async function ce(e,t,n){let r=[`Tracked changes:`,await q(e,[`diff`,`HEAD`,`--binary`])];for(let t of n){let n=await s(f.join(e,t));r.push(`\nUntracked file: ${t}\n`,n.toString(`utf8`))}let{stdout:i}=await p(`codex`,[`exec`,`--ephemeral`,`--ignore-user-config`,`--sandbox`,`read-only`,`--cd`,e,`Return only a concise Conventional Commits message for the supplied working-tree changes. Use a body only when it adds material context.`],{cwd:e,env:t,stderr:`ignore`,stdin:{string:r.join(`
|
|
2
|
+
`)}});return i.trim().replace(/^```(?:text)?\s*|\s*```$/g,``)}async function le(e,t){let r=t.PATH??t.Path??t.path??``,i=v.platform===`win32`?(t.PATHEXT??`.COM;.EXE;.BAT;.CMD`).split(`;`):[``];for(let t of r.split(f.delimiter))for(let r of i)try{return await n(f.join(t||`.`,`${e}${r}`),g.X_OK),!0}catch{}return!1}var N=class extends Error{constructor(){super(`Local dev advanced while this update was being prepared. Nothing was changed. Review the latest update and try again.`)}};async function ue({cwd:e,env:n,localMain:r,onCodexEvent:a,source:o,target:s}){if(o===`dev`&&await we(e,r,s))return{commit:s,devTarget:s};let c=f.resolve(e,await q(e,[`rev-parse`,`--git-common-dir`])),u=f.join(c,`coreframe-managed-dev`);await i(u,{recursive:!0});let d=t(8).toString(`hex`),p=f.join(u,`integration-${d}`);try{if(await K(e,[`worktree`,`add`,`--detach`,p,r]),r!==s)if(o===`dev`)await P(p,n,[`merge`,`--no-edit`,`--no-ff`,`--allow-unrelated-histories`,`--message`,`Merge dev into main`,s],`merge`,a);else{let e=await J(p,[`merge-base`,r,s]);await P(p,n,e?[`rebase`,`--onto`,s,e]:[`rebase`,`--root`,`--onto`,s],`rebase`,a,s)}return{commit:await q(p,[`rev-parse`,`HEAD`]),devTarget:o===`dev`?s:void 0}}finally{await K(e,[`worktree`,`remove`,`--force`,p]).catch(()=>void 0),await l(p,{force:!0,recursive:!0})}}async function de(e,t,n){let r=[`start`,`update ${b} ${t.commit} ${n}`];t.devTarget&&r.push(t.devTarget===t.commit?`verify ${x} ${t.devTarget}`:`update ${x} ${t.commit} ${t.devTarget}`),r.push(`prepare`,`commit`);try{await p(`git`,[`update-ref`,`--stdin`],{cwd:e,stdin:{string:`${r.join(`
|
|
3
|
+
`)}\n`}})}catch(r){if(t.devTarget)try{let[r,i]=await Promise.all([q(e,[`rev-parse`,b]),J(e,[`rev-parse`,x])]);if(r===n&&i!==t.devTarget)throw new N}catch(e){if(e instanceof N)throw e}throw r}}async function P(e,t,n,r,i,a){try{await K(e,n,{env:{GIT_EDITOR:`true`}});return}catch(n){let o=await z(e);if(o.length===0)throw n;try{for(;o.length>0;){await F(e,t,r,o,a?await I(e,a):[],i),await K(e,[`diff`,`--check`]),await K(e,[`add`,`--all`]);let n=await z(e);if(n.length>0)throw Error(`Codex left unresolved paths: ${n.join(`, `)}`);try{await K(e,[r,`--continue`],{env:{GIT_EDITOR:`true`}})}catch(t){if(o=await z(e),o.length===0)throw t;i({commits:a?await I(e,a):[],phase:`progress`});continue}i({commits:a?await I(e,a):[],phase:`progress`}),o=await z(e)}return}catch(t){throw await K(e,[r,`--abort`]).catch(()=>void 0),Error(`Codex could not resolve ${r} conflicts: ${Z(t)}`)}}}async function F(e,t,n,r,i,a){let o=`Resolve the current Git ${n} conflicts cleanly. Edit only files needed for the resolution, preserve intended behavior from both sides, remove all conflict markers, and do not stage files or run Git continuation commands. Conflicted paths: ${r.join(`, `)}`;a({commits:i,message:{kind:`user`,text:o},phase:`start`});let s=p(`codex`,[`exec`,`--ephemeral`,`--ignore-user-config`,`--json`,`--config`,`model_reasoning_effort="low"`,`--sandbox`,`workspace-write`,`--cd`,e,o],{cwd:e,env:t,stdin:`ignore`}),c=``,l=[];try{await Promise.all([R(s.stdout,e=>{let t=L(e);t&&(t.kind===`agent`&&(c=t.text),a({message:t,phase:`message`}))}),R(s.stderr,e=>l.push(e))])}catch(e){a({phase:`error`});let t=l.join(`
|
|
4
|
+
`).trim();throw t?Error(`${Z(e)}\n${t}`):e}a({finalMessage:c||`Codex resolved the conflicts.`,phase:`complete`})}async function I(e,t){let n=await q(e,[`log`,`--reverse`,`--format=%H%x00%s`,`${t}..HEAD`]);return n?n.split(`
|
|
5
|
+
`).map(e=>{let[t,n=``]=e.split(`\0`,2);return{commit:t,shortCommit:t.slice(0,12),subject:n}}):[]}function L(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Codex emitted invalid JSONL output.`)}if(!t||typeof t!=`object`)return;let n=t.item;if(t.type!==`item.completed`||!n||typeof n!=`object`)return;let{text:r,type:i}=n;if(!(typeof r!=`string`||!r.trim())){if(i===`reasoning`)return{kind:`thought`,text:r};if(i===`agent_message`)return{kind:`agent`,text:r}}}async function R(e,t){for await(let n of e)t(n)}async function z(e){return Y(await q(e,[`diff`,`--name-only`,`--diff-filter=U`,`-z`]))}async function fe(e,t,n){await p(X(),[n],{cwd:e,env:t})}function pe(e){if(e instanceof m){let t=e.output.trim();if(t)return t}return Z(e)}async function me({config:e,cwd:t,env:n}){if(!e.database)return;let r=await he({config:e,cwd:t,env:n});try{await p(X(),[`db`,`migrate`],{cwd:t,env:n})}catch(e){throw await r.restore(),e}await r.discard().catch(e=>{console.warn(`Could not remove the managed-development database snapshot: ${Z(e)}`)}),await l(r.directory,{force:!0,recursive:!0})}async function he({config:e,cwd:t,env:n}){let o=f.join(t,`.coreframe`,`managed-dev-backups`);await i(o,{recursive:!0});let s=await a(f.join(o,`refresh-`));if(e.database?.dialect===`sqlite`){let e=[`turso.db`,`turso.db-wal`,`turso.db-shm`],n=new Set;for(let r of e)await ge(f.join(t,`.coreframe`,r),f.join(s,r))&&n.add(r);return{directory:s,async discard(){},async restore(){for(let i of e){let e=f.join(t,`.coreframe`,i);n.has(i)?await r(f.join(s,i),e):await l(e,{force:!0})}}}}if(!n.DATABASE_URL)throw Error(`DATABASE_URL is required to snapshot local PostgreSQL.`);let c=await B(t);if(c)return V({directory:s,connectionString:n.DATABASE_URL,postgres:c});let u=f.join(s,`database.dump`),d=_e(n,n.DATABASE_URL);return await p(`pg_dump`,[`--format=custom`,`--file`,u],{cwd:t,env:d,stdin:`ignore`}),{directory:s,async discard(){},async restore(){await p(`pg_restore`,[`--clean`,`--if-exists`,`--no-owner`,`--dbname`,d.PGDATABASE,u],{cwd:t,env:d,stdin:`ignore`})}}}async function ge(e,t){try{return await r(e,t),!0}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e;return!1}}async function B(e){let t=JSON.parse(await s(f.join(e,`package.json`),`utf8`));if(!(!t.dependencies?.pg&&!t.devDependencies?.pg&&!t.optionalDependencies?.pg))try{return await import(y(`pg`,h(f.join(e,`package.json`)).href))}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ERR_MODULE_NOT_FOUND`)return;throw e}}async function V({directory:e,connectionString:n,postgres:r}){let i=new URL(n),a=decodeURIComponent(i.pathname.slice(1));if(!a)throw Error(`DATABASE_URL must name a PostgreSQL database to snapshot.`);let o=`coreframe_backup_${t(6).toString(`hex`)}`,s=`${o}_failed`,c=new URL(i);c.pathname=a===`postgres`?`/template1`:`/postgres`;let l=new r.Client({connectionString:c.href});await l.connect();try{await U(l,a,!1),await W(l,a),await l.query(`CREATE DATABASE ${G(o)} WITH TEMPLATE ${G(a)}`),await U(l,o,!0)}finally{await U(l,a,!0).catch(()=>void 0),await l.end()}return{directory:e,async discard(){await H(r,c.href,async e=>{await W(e,o),await e.query(`DROP DATABASE ${G(o)}`)})},async restore(){await H(r,c.href,async e=>{await U(e,a,!1),await W(e,a),await e.query(`ALTER DATABASE ${G(a)} RENAME TO ${G(s)}`);try{await e.query(`ALTER DATABASE ${G(o)} RENAME TO ${G(a)}`)}catch(t){throw await e.query(`ALTER DATABASE ${G(s)} RENAME TO ${G(a)}`).catch(()=>void 0),await U(e,a,!0).catch(()=>void 0),t}await W(e,s),await e.query(`DROP DATABASE ${G(s)}`)})}}}async function H(e,t,n){let r=new e.Client({connectionString:t});await r.connect();try{return await n(r)}finally{await r.end()}}async function U(e,t,n){await e.query(`ALTER DATABASE ${G(t)} ALLOW_CONNECTIONS ${n?`true`:`false`}`)}async function W(e,t){await e.query(`SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()`,[t])}function G(e){return`"${e.replaceAll(`"`,`""`)}"`}function _e(e,t){let n=new URL(t);return{...e,PGDATABASE:decodeURIComponent(n.pathname.slice(1)),PGHOST:n.hostname,PGPASSWORD:decodeURIComponent(n.password),PGPORT:n.port||`5432`,PGUSER:decodeURIComponent(n.username)}}function ve(e){return e.some(e=>f.basename(e)===`package.json`||f.basename(e).endsWith(`lock.yaml`)||f.basename(e)===`pnpm-workspace.yaml`)}function ye(e){return e.some(e=>ve([e])||/(^|\/)(vite|coreframe|tsconfig|drizzle)\.[^/]+$/.test(e)||/(^|\/)(drizzle|scripts|src\/api|tauri)(\/|$)/.test(e))}async function be(e,t,n){return{commit:t,shortCommit:t.slice(0,12),source:n,subject:await q(e,[`show`,`-s`,`--format=%s`,t])}}async function xe(e){try{let t=await o(e,`wx`);await t.writeFile(`${v.pid}\n`),await t.close()}catch(t){if(!(t instanceof Error&&`code`in t&&t.code===`EEXIST`))throw t;let n=(await s(e,`utf8`).catch(()=>`unknown`)).trim(),r=Number(n);if(Number.isInteger(r)&&!Se(r)){await u(e).catch(()=>void 0),await xe(e);return}throw Error(`Managed development is already owned by PID ${n}.`)}}function Se(e){try{return v.kill(e,0),!0}catch(e){return!(e instanceof Error&&`code`in e&&e.code===`ESRCH`)}}async function Ce(e){e&&(await s(e,`utf8`).catch(()=>void 0))?.trim()===String(v.pid)&&await u(e).catch(()=>void 0)}async function K(e,t,{env:n}={}){return p(`git`,t,{cwd:e,env:n,stdin:`ignore`})}async function q(e,t){return(await K(e,t)).stdout.trim()}async function J(e,t){try{return await q(e,t)||void 0}catch(e){if(e instanceof m&&e.exitCode&&e.exitCode>0)return;throw e}}async function we(e,t,n){try{return await K(e,[`merge-base`,`--is-ancestor`,t,n]),!0}catch(e){if(e instanceof m&&e.exitCode===1)return!1;throw e}}function Te(e,t){return e.length===t.length&&[...e].sort().every((e,n)=>e===[...t].sort()[n])}function Y(e){return e.split(`\0`).filter(Boolean)}function Ee(e){return e.split(/\r?\n/,1)[0]??``}function De(e){return e.type===`acknowledge-codex`?`Acknowledging Codex result`:e.type===`dismiss-check`?`Dismissing managed development check`:e.type===`message`?`Generating commit message`:e.type===`commit`?`Committing local changes`:e.type===`apply`?`Integrating accepted update`:e.type===`prepare`?`Reviewing working tree`:e.type===`retry-install`?`Retrying dependency installation`:e.type===`reset-database`?`Resetting local database`:`Aborting refresh`}function X(){return v.platform===`win32`?`pnpm.cmd`:`pnpm`}function Z(e){return e instanceof Error?e.message:String(e)}export{C as isManagedDevCheckout,w as isPrimaryCheckout,E as startManagedDevSession};
|