@teispace/next-maker 1.18.0 → 1.19.1

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.19.1](https://github.com/teispace/npm-packages/compare/next-maker-v1.19.0...next-maker-v1.19.1) (2026-04-29)
4
+
5
+
6
+ ### Code Refactoring
7
+
8
+ * remove console logs from loading and error state handlers in hook template ([6cd953a](https://github.com/teispace/npm-packages/commit/6cd953a3f9b82dc37d249644913bbf6110c878b3))
9
+
10
+ ## [1.19.0](https://github.com/teispace/npm-packages/compare/next-maker-v1.18.0...next-maker-v1.19.0) (2026-04-28)
11
+
12
+
13
+ ### Features
14
+
15
+ * 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))
16
+
3
17
  ## [1.18.0](https://github.com/teispace/npm-packages/compare/next-maker-v1.17.1...next-maker-v1.18.0) (2026-04-26)
4
18
 
5
19
 
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;return`import type { PersistConfig } from 'redux-persist';
334
- import storage from 'redux-persist/lib/storage';
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
 
@@ -403,12 +414,10 @@ export const ${r} = () => {
403
414
 
404
415
  const handleSetLoading = (loading: boolean) => {
405
416
  dispatch(setLoading(loading));
406
- console.log('Loading state updated:', loading);
407
417
  };
408
418
 
409
419
  const handleSetError = (error: string | null) => {
410
420
  dispatch(setError(error));
411
- console.log('Error state updated:', error);
412
421
  };
413
422
 
414
423
  return {
@@ -744,6 +753,7 @@ ${h}`}),t=t.replace(/export const RootProvider = \(\{([\s\S]*?)\}:\s*RootProvide
744
753
  import { hasLocale } from 'next-intl';
745
754
  import { notFound } from 'next/navigation';
746
755
  import { getMessages, getTimeZone, setRequestLocale } from 'next-intl/server';
756
+ import { getLocaleDirection } from '@/lib/config/app-locales';
747
757
  ${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
758
 
749
759
  export function generateStaticParams() {
@@ -761,7 +771,7 @@ export function generateStaticParams() {
761
771
  setRequestLocale(locale);
762
772
 
763
773
  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';
774
+ `+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
775
  import { setRequestLocale } from 'next-intl/server';
766
776
  ${i}`),i=i.replace(/export default function Home\(\)/,`type Props = {
767
777
  params: Promise<{ locale: string }>;
@@ -799,6 +809,8 @@ ${e.map(({key:t,value:n})=>` { key: '${t}', value: '${n}' },`).join(`
799
809
  },`,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
810
  import * as path from 'node:path';
801
811
 
812
+ const checkOnly = process.argv.includes('--check');
813
+
802
814
  const envPath = path.join(process.cwd(), '.env');
803
815
  const examplePath = path.join(process.cwd(), '.env.example');
804
816
 
@@ -856,12 +868,18 @@ if (fs.existsSync(examplePath)) {
856
868
  currentExampleContent = fs.readFileSync(examplePath, 'utf-8');
857
869
  }
858
870
 
859
- if (currentExampleContent !== newExampleContent) {
860
- fs.writeFileSync(examplePath, newExampleContent);
861
- console.log('\u2705 Synchronized .env.example with .env');
862
- } else {
871
+ if (currentExampleContent === newExampleContent) {
863
872
  console.log('\u2728 .env.example is already up to date');
873
+ process.exit(0);
864
874
  }
875
+
876
+ if (checkOnly) {
877
+ console.error('\u274C .env.example is out of sync with .env. Run "yarn env:sync" to update.');
878
+ process.exit(1);
879
+ }
880
+
881
+ fs.writeFileSync(examplePath, newExampleContent);
882
+ console.log('\u2705 Synchronized .env.example with .env');
865
883
  `,ar=`/**
866
884
  * Walks every identifier in the project and flags any whose resolved TypeScript
867
885
  * symbol carries a \`@deprecated\` JSDoc tag. Catches deprecated API usage that