@teispace/next-maker 1.18.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/index.js +27 -7
- package/dist/index.js.map +3 -3
- package/dist/src/generators/templates/persist.template.d.ts.map +1 -1
- package/dist/src/services/setup/i18n/injectors.d.ts.map +1 -1
- package/dist/src/services/setup/validate-scripts/scripts.d.ts +1 -1
- package/dist/src/services/setup/validate-scripts/scripts.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.19.0](https://github.com/teispace/npm-packages/compare/next-maker-v1.18.0...next-maker-v1.19.0) (2026-04-28)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* enhance persist template with migrations and versioning; update HTML lang direction in injectors; add check-only option in env sync script ([e49240c](https://github.com/teispace/npm-packages/commit/e49240c97064a10f3f43bee518b9a02da2879545))
|
|
9
|
+
|
|
3
10
|
## [1.18.0](https://github.com/teispace/npm-packages/compare/next-maker-v1.17.1...next-maker-v1.18.0) (2026-04-26)
|
|
4
11
|
|
|
5
12
|
|
package/dist/index.js
CHANGED
|
@@ -330,14 +330,25 @@ export { ${n} } from './hooks/${n}';
|
|
|
330
330
|
export * from './types/${r}.types';${o?`
|
|
331
331
|
export * from './store';`:""}${i?`
|
|
332
332
|
export * from './services/${r}.service';`:""}
|
|
333
|
-
`};var dn=e=>{let{componentName:r,camelName:t,typesImportPath:n}=e
|
|
334
|
-
import storage from '
|
|
333
|
+
`};var dn=e=>{let{componentName:r,camelName:t,typesImportPath:n}=e,o=`${t.toUpperCase()}_PERSIST_VERSION`;return`import { createMigrate, type PersistConfig, type PersistedState } from 'redux-persist';
|
|
334
|
+
import storage from '@/store/storage';
|
|
335
335
|
import type { ${r}State } from '${n}';
|
|
336
336
|
|
|
337
|
+
const ${o} = 1;
|
|
338
|
+
|
|
339
|
+
const migrations = {
|
|
340
|
+
// Bump ${o} and add a migration here when ${r}State's
|
|
341
|
+
// shape changes. Receives the previously-persisted state, returns the new
|
|
342
|
+
// shape. Returning \`undefined\` discards stale state.
|
|
343
|
+
// 2: (state) => ({ ...state, newField: defaultValue }),
|
|
344
|
+
} satisfies Record<number, (state: PersistedState) => PersistedState>;
|
|
345
|
+
|
|
337
346
|
export const ${t}PersistConfig: PersistConfig<${r}State> = {
|
|
338
347
|
key: '${t}',
|
|
339
348
|
storage,
|
|
349
|
+
version: ${o},
|
|
340
350
|
// whitelist: ['someField'], // Specify which fields to persist
|
|
351
|
+
migrate: createMigrate(migrations, { debug: false }),
|
|
341
352
|
};
|
|
342
353
|
`};var un=e=>{let{componentName:r,camelName:t,sliceName:n}=e;return`import { RootState } from '@/store/rootReducer';
|
|
343
354
|
|
|
@@ -744,6 +755,7 @@ ${h}`}),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProvide
|
|
|
744
755
|
import { hasLocale } from 'next-intl';
|
|
745
756
|
import { notFound } from 'next/navigation';
|
|
746
757
|
import { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';
|
|
758
|
+
import { getLocaleDirection } from '@/lib/config/app-locales';
|
|
747
759
|
${i}`),!i.includes("generateStaticParams")){let p=i.indexOf("};",i.indexOf("export const metadata"));if(p!==-1){let d=p+2;i=i.slice(0,d)+`
|
|
748
760
|
|
|
749
761
|
export function generateStaticParams() {
|
|
@@ -761,7 +773,7 @@ export function generateStaticParams() {
|
|
|
761
773
|
setRequestLocale(locale);
|
|
762
774
|
|
|
763
775
|
const [messages, timeZone] = await Promise.all([getMessages(), getTimeZone()]);
|
|
764
|
-
`+i.slice(h+1)}i=i.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),i=i.replace(/<html lang="en"/,"<html lang={locale}")}await f(o,i),await T(r)}if(m(t)){let o=re.join(n,"page.tsx"),i=await u(t);i.includes("next-intl")||(i=`import { SupportedLocale } from '@/types/i18n';
|
|
776
|
+
`+i.slice(h+1)}i=i.replace(/<RootProvider>/,"<RootProvider locale={locale} messages={messages} timeZone={timeZone}>"),i=i.replace(/<html lang="en"/,"<html lang={locale} dir={getLocaleDirection(locale)}")}await f(o,i),await T(r)}if(m(t)){let o=re.join(n,"page.tsx"),i=await u(t);i.includes("next-intl")||(i=`import { SupportedLocale } from '@/types/i18n';
|
|
765
777
|
import { setRequestLocale } from 'next-intl/server';
|
|
766
778
|
${i}`),i=i.replace(/export default function Home\(\)/,`type Props = {
|
|
767
779
|
params: Promise<{ locale: string }>;
|
|
@@ -799,6 +811,8 @@ ${e.map(({key:t,value:n})=>` { key: '${t}', value: '${n}' },`).join(`
|
|
|
799
811
|
},`,we=e=>Ta.test(e),or=(e,r=Ro)=>{if(we(e))return e;if(!Eo.test(e))throw new Error("Could not locate `const nextConfig: NextConfig = {` in next.config.ts.");return e.replace(Eo,`$1${Ea(r)}`)};var Be=async e=>{let r=R("Adding security headers to next.config.ts...");try{let t=Ra.join(e,c.NEXT_CONFIG);if(!m(t))throw new Error(`${c.NEXT_CONFIG} not found.`);let n=await u(t);if(we(n)){r.succeed("Security headers already configured.");return}let o=or(n);await f(t,o),r.succeed($a.green("Security headers added."))}catch(t){throw r.fail("Failed to add security headers."),t}};var $o={id:"security-headers",name:"Security Headers",description:"Hardened HTTP headers in next.config.ts",detect:async e=>{let r=ba.join(e,c.NEXT_CONFIG);return m(r)?we(await u(r)):!1},files:[],packages:[],scripts:[],injections:[{file:c.NEXT_CONFIG,description:"headers() function in next.config.ts",presence:/^\s+headers\s*:/m,removePattern:/\s+headers:\s*async\s*\(\)\s*=>\s*\{[\s\S]*?\n\s{0,2}\},/m}],apply:Be};w();P();import Oa from"node:path";w();import Na from"node:fs/promises";import ae from"node:path";import Ia from"degit";import Aa from"picocolors";P();var ka=["vitest","jsdom","@vitejs/plugin-react","@testing-library/dom","@testing-library/jest-dom","@testing-library/react","@testing-library/user-event"],Xe=async e=>{let r=R("Setting up testing (Vitest + RTL)..."),t=ae.join(e,".next-maker-temp-tests");try{let n=ae.join(e,c.VITEST_CONFIG);if(m(n)){r.fail("Testing is already set up (vitest.config.ts exists).");return}r.text="Fetching assets from starter repo...",await Ia("teispace/nextjs-starter",{cache:!1,force:!0,verbose:!1}).clone(t),await _(ae.join(t,c.VITEST_CONFIG),ae.join(e,c.VITEST_CONFIG));let i=ae.join(e,c.TEST_DIR);await Na.mkdir(i,{recursive:!0}),await _(ae.join(t,c.TEST_DIR,"setup.ts"),ae.join(i,"setup.ts"));let s=ae.join(e,c.PACKAGE_JSON),a=JSON.parse(await u(s)),p={...a.dependencies,...a.devDependencies},d=!!(p["@reduxjs/toolkit"]&&p["react-redux"]),g=!!p["next-intl"];await ne(e,{redux:d,i18n:g}),await k(s,x=>(x.scripts=x.scripts??{},x.scripts.test=x.scripts.test??"vitest run",x.scripts["test:watch"]=x.scripts["test:watch"]??"vitest",x.scripts["test:coverage"]=x.scripts["test:coverage"]??"vitest run --coverage",typeof x.scripts.validate=="string"&&!/\byarn\s+test(?![:\w])/.test(x.scripts.validate)&&(x.scripts.validate=x.scripts.validate.replace(/(\byarn\s+check:deprecated\s*)(&&)/,"$1&& yarn test $2")),x)),r.text="Installing testing devDependencies...";let h=await O(e);await ue(e,h,ka),r.text="Formatting code...",await U(e,h,"lint:fix"),r.succeed(Aa.green("Testing setup complete."))}catch(n){throw r.fail("Failed to set up testing."),n}finally{await S(t)}};var bo={id:"tests",name:"Tests",description:"Vitest + React Testing Library + jsdom",detect:async e=>m(Oa.join(e,c.VITEST_CONFIG)),files:[{path:c.VITEST_CONFIG,generated:!0},{path:"test",generated:!0,isDir:!0,containsUserContent:!0,removeHint:"holds setup.ts / test-utils.tsx and any helpers you added \u2014 review before deleting"}],packages:[{name:"vitest",kind:"devDependency"},{name:"jsdom",kind:"devDependency"},{name:"@vitejs/plugin-react",kind:"devDependency"},{name:"@testing-library/dom",kind:"devDependency"},{name:"@testing-library/jest-dom",kind:"devDependency"},{name:"@testing-library/react",kind:"devDependency"},{name:"@testing-library/user-event",kind:"devDependency"}],scripts:[{name:"test",expectedValue:"vitest run"},{name:"test:watch",expectedValue:"vitest"}],injections:[],apply:Xe};P();import La from"node:path";w();import No from"node:path";import ja from"picocolors";P();var _a={npm:"npm run",yarn:"yarn",pnpm:"pnpm",bun:"bun run"},Fa=e=>{let r=_a[e];return["ci:check","type-check","check:deprecated","test","build"].map(t=>`${r} ${t}`).join(" && ")},ir=(e,r)=>{let t={...e.scripts??{}},n={...e.devDependencies??{}};return t["env:sync"]||(t["env:sync"]="tsx scripts/sync-env.ts"),t["check:deprecated"]||(t["check:deprecated"]="tsx scripts/check-deprecated.ts"),t["type-check"]||(t["type-check"]="tsc --noEmit"),t.validate||(t.validate=Fa(r)),!n.tsx&&!e.dependencies?.hasOwnProperty("tsx")&&(n.tsx="*"),{...e,scripts:t,devDependencies:n}};var sr=`import * as fs from 'node:fs';
|
|
800
812
|
import * as path from 'node:path';
|
|
801
813
|
|
|
814
|
+
const checkOnly = process.argv.includes('--check');
|
|
815
|
+
|
|
802
816
|
const envPath = path.join(process.cwd(), '.env');
|
|
803
817
|
const examplePath = path.join(process.cwd(), '.env.example');
|
|
804
818
|
|
|
@@ -856,12 +870,18 @@ if (fs.existsSync(examplePath)) {
|
|
|
856
870
|
currentExampleContent = fs.readFileSync(examplePath, 'utf-8');
|
|
857
871
|
}
|
|
858
872
|
|
|
859
|
-
if (currentExampleContent
|
|
860
|
-
fs.writeFileSync(examplePath, newExampleContent);
|
|
861
|
-
console.log('\u2705 Synchronized .env.example with .env');
|
|
862
|
-
} else {
|
|
873
|
+
if (currentExampleContent === newExampleContent) {
|
|
863
874
|
console.log('\u2728 .env.example is already up to date');
|
|
875
|
+
process.exit(0);
|
|
864
876
|
}
|
|
877
|
+
|
|
878
|
+
if (checkOnly) {
|
|
879
|
+
console.error('\u274C .env.example is out of sync with .env. Run "yarn env:sync" to update.');
|
|
880
|
+
process.exit(1);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
fs.writeFileSync(examplePath, newExampleContent);
|
|
884
|
+
console.log('\u2705 Synchronized .env.example with .env');
|
|
865
885
|
`,ar=`/**
|
|
866
886
|
* Walks every identifier in the project and flags any whose resolved TypeScript
|
|
867
887
|
* symbol carries a \`@deprecated\` JSDoc tag. Catches deprecated API usage that
|