@inglorious/create-app 1.2.0 → 1.4.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/README.md +8 -2
- package/bin/index.js +30 -49
- package/bin/lib/app-jsx.js +2 -4
- package/bin/lib/app-lit.js +6 -10
- package/bin/lib/app.js +22 -12
- package/bin/lib/cli.js +3 -0
- package/bin/lib/constants.js +3 -1
- package/bin/lib/features.js +29 -0
- package/bin/lib/pwa.js +3 -1
- package/package.json +2 -2
- package/templates/ssx-ts/src/pages/about.ts +5 -5
- package/templates/ssx-ts/types/index.d.ts +13 -7
- package/templates/ts/package.json +2 -1
- package/templates/ts/src/store/index.ts +2 -2
- package/templates/ts/types/index.d.ts +10 -6
- package/templates/ts-jsx/package.json +2 -1
- package/templates/ts-jsx/src/app.tsx +0 -1
- package/templates/ts-jsx/src/store/index.ts +2 -2
- package/templates/ts-jsx/types/index.d.ts +10 -6
- package/templates/ts-vue/package.json +2 -1
- package/templates/ts-vue/src/main.ts +1 -1
- package/templates/ts-vue/src/store/index.ts +2 -2
- package/templates/ts-vue/types/index.d.ts +6 -8
package/README.md
CHANGED
|
@@ -36,10 +36,16 @@ For the JavaScript and TypeScript Vite templates, the CLI then asks about the ap
|
|
|
36
36
|
| Translate the app? | `--i18n` / `--no-i18n`, `--languages=en,it` | `@inglorious/i18n`, a catalogue per language and a language picker; the first language is the default |
|
|
37
37
|
| Enable PWA support? | `--pwa` / `--no-pwa` | `vite-plugin-pwa`, a manifest, icons and service worker registration |
|
|
38
38
|
|
|
39
|
-
The app is generated in the syntax you chose: lit-html, JSX or Vue. Every question answered
|
|
39
|
+
The app is generated in the syntax you chose: lit-html, JSX or Vue. Every question answered on the command line is skipped, so a project can be created without any prompt:
|
|
40
|
+
|
|
41
|
+
| Question | Argument or flag |
|
|
42
|
+
| --------------------------- | -------------------------------------------- |
|
|
43
|
+
| What is your project named? | The first argument, such as `my-app` |
|
|
44
|
+
| Select a template | `--template=minimal\|js\|ts\|ssx-js\|ssx-ts` |
|
|
45
|
+
| Select a rendering syntax | `--syntax=lit-html\|jsx\|vue` |
|
|
40
46
|
|
|
41
47
|
```bash
|
|
42
|
-
npm create @inglorious/app@latest -- --ui --theme=material --routing --transitions --icons=material --languages=en,it --mobile
|
|
48
|
+
npm create @inglorious/app@latest -- my-app --template=ts --syntax=jsx --ui --theme=material --routing --transitions --icons=material --languages=en,it --no-mobile --no-pwa
|
|
43
49
|
```
|
|
44
50
|
|
|
45
51
|
## Templates
|
package/bin/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
USER_ARG_START_INDEX,
|
|
17
17
|
VITE_APP_TEMPLATES,
|
|
18
18
|
} from "./lib/constants.js"
|
|
19
|
+
import { SYNTAXES, TEMPLATES } from "./lib/features.js"
|
|
19
20
|
import { copyDir } from "./lib/file.js"
|
|
20
21
|
import { addMobileSupport } from "./lib/mobile.js"
|
|
21
22
|
import { addPwaSupport } from "./lib/pwa.js"
|
|
@@ -25,6 +26,8 @@ async function main() {
|
|
|
25
26
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
26
27
|
const templatesRoot = path.join(__dirname, "../templates")
|
|
27
28
|
const cliOptions = parseCliOptions(process.argv.slice(USER_ARG_START_INDEX))
|
|
29
|
+
validateChoice("template", cliOptions.template, TEMPLATES)
|
|
30
|
+
validateChoice("syntax", cliOptions.syntax, SYNTAXES)
|
|
28
31
|
|
|
29
32
|
let canceled = false
|
|
30
33
|
|
|
@@ -33,45 +36,19 @@ async function main() {
|
|
|
33
36
|
return false
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
const
|
|
39
|
+
const answers = await prompts(
|
|
37
40
|
[
|
|
38
41
|
{
|
|
39
|
-
type: "text",
|
|
42
|
+
type: cliOptions.projectName ? null : "text",
|
|
40
43
|
name: "projectName",
|
|
41
44
|
message: "What is your project named?",
|
|
42
45
|
initial: "my-app",
|
|
43
46
|
},
|
|
44
47
|
{
|
|
45
|
-
type: "select",
|
|
48
|
+
type: cliOptions.template ? null : "select",
|
|
46
49
|
name: "baseTemplate",
|
|
47
50
|
message: "Select a template",
|
|
48
|
-
choices:
|
|
49
|
-
{
|
|
50
|
-
title: "Minimal",
|
|
51
|
-
description: "A single HTML file for a zero-build setup",
|
|
52
|
-
value: "minimal",
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
title: "JavaScript",
|
|
56
|
-
description: "A vanilla JavaScript setup with Vite",
|
|
57
|
-
value: "js",
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
title: "TypeScript",
|
|
61
|
-
description: "A TypeScript setup with Vite",
|
|
62
|
-
value: "ts",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
title: "SSX (JavaScript)",
|
|
66
|
-
description: "Static Site Xecution with JavaScript",
|
|
67
|
-
value: "ssx-js",
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
title: "SSX (TypeScript)",
|
|
71
|
-
description: "Static Site Xecution with TypeScript",
|
|
72
|
-
value: "ssx-ts",
|
|
73
|
-
},
|
|
74
|
-
],
|
|
51
|
+
choices: toChoices(TEMPLATES),
|
|
75
52
|
},
|
|
76
53
|
],
|
|
77
54
|
{ onCancel },
|
|
@@ -82,31 +59,18 @@ async function main() {
|
|
|
82
59
|
return
|
|
83
60
|
}
|
|
84
61
|
|
|
62
|
+
const projectName = cliOptions.projectName ?? answers.projectName
|
|
63
|
+
const baseTemplate = cliOptions.template ?? answers.baseTemplate
|
|
64
|
+
|
|
85
65
|
let renderer = "lit-html"
|
|
86
66
|
|
|
87
67
|
if (baseTemplate !== "minimal") {
|
|
88
68
|
const { selectedRenderer } = await prompts(
|
|
89
69
|
{
|
|
90
|
-
type: "select",
|
|
70
|
+
type: cliOptions.syntax ? null : "select",
|
|
91
71
|
name: "selectedRenderer",
|
|
92
72
|
message: "Select a rendering syntax",
|
|
93
|
-
choices:
|
|
94
|
-
{
|
|
95
|
-
title: "lit-html (default)",
|
|
96
|
-
description: "Tagged template literals (html`<div>...</div>`)",
|
|
97
|
-
value: "lit-html",
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
title: "JSX",
|
|
101
|
-
description: "JSX/TSX syntax (<div>...</div>)",
|
|
102
|
-
value: "jsx",
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
title: "Vue",
|
|
106
|
-
description: "Vue SFC-style templates",
|
|
107
|
-
value: "vue",
|
|
108
|
-
},
|
|
109
|
-
],
|
|
73
|
+
choices: toChoices(SYNTAXES),
|
|
110
74
|
},
|
|
111
75
|
{ onCancel },
|
|
112
76
|
)
|
|
@@ -116,7 +80,9 @@ async function main() {
|
|
|
116
80
|
return
|
|
117
81
|
}
|
|
118
82
|
|
|
119
|
-
renderer = selectedRenderer
|
|
83
|
+
renderer = cliOptions.syntax ?? selectedRenderer
|
|
84
|
+
} else if (cliOptions.syntax && cliOptions.syntax !== "lit-html") {
|
|
85
|
+
console.warn("The minimal template is only available with lit-html.")
|
|
120
86
|
}
|
|
121
87
|
|
|
122
88
|
let features = {
|
|
@@ -223,6 +189,21 @@ async function main() {
|
|
|
223
189
|
}
|
|
224
190
|
}
|
|
225
191
|
|
|
192
|
+
function toChoices(options) {
|
|
193
|
+
return Object.entries(options).map(([value, option]) => ({
|
|
194
|
+
value,
|
|
195
|
+
...option,
|
|
196
|
+
}))
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function validateChoice(flag, value, options) {
|
|
200
|
+
if (value !== null && !options[value]) {
|
|
201
|
+
throw new Error(
|
|
202
|
+
`Unknown ${flag} "${value}". Choose one of: ${Object.keys(options).join(", ")}.`,
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
226
207
|
function getLatestVersion(packageName) {
|
|
227
208
|
try {
|
|
228
209
|
const version = execSync(`npm view ${packageName} version`, {
|
package/bin/lib/app-jsx.js
CHANGED
|
@@ -252,9 +252,7 @@ export function messageSource(app) {
|
|
|
252
252
|
}
|
|
253
253
|
if (app.i18n) imports.push('import { t } from "../i18n"')
|
|
254
254
|
const greeting = app.i18n ? '{t("message.hello", { who })}' : "Hello {who}"
|
|
255
|
-
const
|
|
256
|
-
? "export const Message: MessageType = {"
|
|
257
|
-
: "export const Message = {"
|
|
255
|
+
const annotation = app.isTypeScript ? ": MessageType" : ""
|
|
258
256
|
|
|
259
257
|
const span = app.i18n
|
|
260
258
|
? ` <span onClick={() => api.notify(\`#\${entity.id}:click\`)}>
|
|
@@ -264,7 +262,7 @@ export function messageSource(app) {
|
|
|
264
262
|
|
|
265
263
|
const head = imports.length ? `${importBlock(imports)}\n\n` : ""
|
|
266
264
|
|
|
267
|
-
return `${head}${
|
|
265
|
+
return `${head}export const Message${annotation} = {
|
|
268
266
|
click(entity) {
|
|
269
267
|
entity.isUpperCase = !entity.isUpperCase
|
|
270
268
|
},
|
package/bin/lib/app-lit.js
CHANGED
|
@@ -187,7 +187,7 @@ export function homeSource(app, { showcase }) {
|
|
|
187
187
|
imports.push('import { Icon } from "@inglorious/ui/icon"')
|
|
188
188
|
}
|
|
189
189
|
if (app.isTypeScript) {
|
|
190
|
-
imports.push('import type {
|
|
190
|
+
imports.push('import type { HomeType } from "../../types"')
|
|
191
191
|
}
|
|
192
192
|
if (app.i18n) imports.push('import { t } from "../i18n"')
|
|
193
193
|
|
|
@@ -207,14 +207,12 @@ ${showcase
|
|
|
207
207
|
</p>`
|
|
208
208
|
: ""
|
|
209
209
|
|
|
210
|
-
const
|
|
211
|
-
? "render(entity: HomeEntity, api: AppApi)"
|
|
212
|
-
: "render(entity, api)"
|
|
210
|
+
const annotation = app.isTypeScript ? ": HomeType" : ""
|
|
213
211
|
|
|
214
212
|
return `${importBlock(imports)}
|
|
215
213
|
|
|
216
|
-
export const Home = {
|
|
217
|
-
|
|
214
|
+
export const Home${annotation} = {
|
|
215
|
+
render(entity, api) {
|
|
218
216
|
return html\`
|
|
219
217
|
<h1>${text("home.title", "Welcome")}</h1>
|
|
220
218
|
<p>
|
|
@@ -253,13 +251,11 @@ export function messageSource(app) {
|
|
|
253
251
|
}
|
|
254
252
|
if (app.i18n) imports.push('import { t } from "../i18n"')
|
|
255
253
|
const greeting = app.i18n ? '${t("message.hello", { who })}' : "Hello ${who}"
|
|
256
|
-
const
|
|
257
|
-
? "export const Message: MessageType = {"
|
|
258
|
-
: "export const Message = {"
|
|
254
|
+
const annotation = app.isTypeScript ? ": MessageType" : ""
|
|
259
255
|
|
|
260
256
|
return `${importBlock(imports)}
|
|
261
257
|
|
|
262
|
-
${
|
|
258
|
+
export const Message${annotation} = {
|
|
263
259
|
click(entity) {
|
|
264
260
|
entity.isUpperCase = !entity.isUpperCase
|
|
265
261
|
},
|
package/bin/lib/app.js
CHANGED
|
@@ -227,9 +227,7 @@ main {
|
|
|
227
227
|
|
|
228
228
|
function storeSource(app) {
|
|
229
229
|
const imports = [
|
|
230
|
-
|
|
231
|
-
? 'import { createStore, type TypesConfig } from "@inglorious/store"'
|
|
232
|
-
: 'import { createStore } from "@inglorious/store"',
|
|
230
|
+
'import { createStore } from "@inglorious/store"',
|
|
233
231
|
componentImport(app, "Home", "../pages/home"),
|
|
234
232
|
componentImport(app, "Message", "../types/message"),
|
|
235
233
|
'import { entities } from "./entities"',
|
|
@@ -250,14 +248,13 @@ function storeSource(app) {
|
|
|
250
248
|
const types = ["Message", "Home"]
|
|
251
249
|
if (app.routing) types.push("About", "Router")
|
|
252
250
|
if (app.i18n) types.push("I18n")
|
|
253
|
-
const
|
|
254
|
-
const oneLine = ` types: { ${types.join(", ")} }${cast},`
|
|
251
|
+
const oneLine = ` types: { ${types.join(", ")} },`
|
|
255
252
|
const typesValue =
|
|
256
253
|
oneLine.length <= LINE_WIDTH
|
|
257
254
|
? oneLine
|
|
258
255
|
: ` types: {
|
|
259
256
|
${types.map((type) => ` ${type},`).join("\n")}
|
|
260
|
-
}
|
|
257
|
+
},`
|
|
261
258
|
const generics = app.isTypeScript ? "<AppEntity, AppState>" : ""
|
|
262
259
|
|
|
263
260
|
return `${importBlock(imports)}
|
|
@@ -333,14 +330,13 @@ export const { I18n, t, ready } = createI18n({
|
|
|
333
330
|
function typesSource(app) {
|
|
334
331
|
const imports = [
|
|
335
332
|
'import "./vite-end"',
|
|
336
|
-
'import type {
|
|
333
|
+
'import type {\n BaseEntity,\n EntitiesState,\n EntityType,\n} from "@inglorious/store"',
|
|
337
334
|
'import type { Api, TemplateResult } from "@inglorious/web"',
|
|
338
335
|
]
|
|
339
336
|
const entities = ["MessageEntity", "HomeEntity"]
|
|
340
337
|
const declarations = [
|
|
341
338
|
`export interface MessageEntity extends BaseEntity {
|
|
342
339
|
type: "Message"
|
|
343
|
-
id?: string
|
|
344
340
|
who: string
|
|
345
341
|
isUpperCase?: boolean
|
|
346
342
|
}`,
|
|
@@ -362,7 +358,7 @@ function typesSource(app) {
|
|
|
362
358
|
`export interface AboutEntity extends BaseEntity {
|
|
363
359
|
type: "About"
|
|
364
360
|
}`,
|
|
365
|
-
`export interface AppRouterEntity extends
|
|
361
|
+
`export interface AppRouterEntity extends RouterEntity {
|
|
366
362
|
type: "Router"
|
|
367
363
|
}`,
|
|
368
364
|
)
|
|
@@ -373,7 +369,7 @@ function typesSource(app) {
|
|
|
373
369
|
imports.push('import type { I18nEntity } from "@inglorious/i18n"')
|
|
374
370
|
entities.push("AppI18nEntity")
|
|
375
371
|
declarations.push(
|
|
376
|
-
`export interface AppI18nEntity extends
|
|
372
|
+
`export interface AppI18nEntity extends I18nEntity {
|
|
377
373
|
type: "I18n"
|
|
378
374
|
}`,
|
|
379
375
|
)
|
|
@@ -394,9 +390,23 @@ ${state.join("\n")}
|
|
|
394
390
|
|
|
395
391
|
export type AppApi = Api<AppEntity, AppState>
|
|
396
392
|
|
|
397
|
-
|
|
393
|
+
// Each type's events and their payloads. Declare types with \`type\`, not
|
|
394
|
+
// \`interface\`: an interface does not fit the store's \`types\`.
|
|
395
|
+
export type MessageType = {
|
|
398
396
|
click: (entity: MessageEntity) => void
|
|
399
|
-
render: (entity: MessageEntity, api: AppApi) => TemplateResult
|
|
397
|
+
render: (entity: MessageEntity, api: AppApi) => TemplateResult
|
|
398
|
+
}
|
|
399
|
+
${
|
|
400
|
+
app.renderer === "lit-html"
|
|
401
|
+
? `
|
|
402
|
+
export type HomeType = {
|
|
403
|
+
render: (entity: HomeEntity, api: AppApi) => TemplateResult
|
|
404
|
+
}
|
|
405
|
+
`
|
|
406
|
+
: ""
|
|
400
407
|
}
|
|
408
|
+
// A shorthand for a type: \`{ ... } satisfies AppType<MessageEntity>\` infers
|
|
409
|
+
// its handlers' parameters, but neither lists its events nor types payloads.
|
|
410
|
+
export type AppType<TEntity extends AppEntity> = EntityType<TEntity, AppApi>
|
|
401
411
|
`
|
|
402
412
|
}
|
package/bin/lib/cli.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export function parseCliOptions(args) {
|
|
2
2
|
return {
|
|
3
|
+
projectName: args.find((arg) => !arg.startsWith("-")) ?? null,
|
|
4
|
+
template: readValueFlag(args, "template"),
|
|
5
|
+
syntax: readValueFlag(args, "syntax"),
|
|
3
6
|
mobile: readBooleanFlag(args, "mobile"),
|
|
4
7
|
pwa: readBooleanFlag(args, "pwa"),
|
|
5
8
|
ui: readBooleanFlag(args, "ui"),
|
package/bin/lib/constants.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export const CAPACITOR_VERSION = "^8.5.3"
|
|
2
2
|
export const VITE_PLUGIN_PWA_VERSION = "^2.0.0"
|
|
3
3
|
export const VITE_PWA_ASSETS_GENERATOR_VERSION = "^2.0.0"
|
|
4
|
-
|
|
4
|
+
// TypeScript 7 has no JavaScript API, which typescript-eslint and the
|
|
5
|
+
// Capacitor CLI import, so `typescript` stays on 6.
|
|
6
|
+
export const TYPESCRIPT_VERSION = "npm:@typescript/typescript6@^6.0.2"
|
|
5
7
|
export const WORKBOX_WINDOW_VERSION = "^7.4.1"
|
|
6
8
|
|
|
7
9
|
export const INDENTATION = 2
|
package/bin/lib/features.js
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
// The choices create-app offers for lit-html apps, and what each one brings.
|
|
2
2
|
|
|
3
|
+
export const TEMPLATES = {
|
|
4
|
+
minimal: {
|
|
5
|
+
title: "Minimal",
|
|
6
|
+
description: "A single HTML file for a zero-build setup",
|
|
7
|
+
},
|
|
8
|
+
js: {
|
|
9
|
+
title: "JavaScript",
|
|
10
|
+
description: "A vanilla JavaScript setup with Vite",
|
|
11
|
+
},
|
|
12
|
+
ts: { title: "TypeScript", description: "A TypeScript setup with Vite" },
|
|
13
|
+
"ssx-js": {
|
|
14
|
+
title: "SSX (JavaScript)",
|
|
15
|
+
description: "Static Site Xecution with JavaScript",
|
|
16
|
+
},
|
|
17
|
+
"ssx-ts": {
|
|
18
|
+
title: "SSX (TypeScript)",
|
|
19
|
+
description: "Static Site Xecution with TypeScript",
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const SYNTAXES = {
|
|
24
|
+
"lit-html": {
|
|
25
|
+
title: "lit-html (default)",
|
|
26
|
+
description: "Tagged template literals (html`<div>...</div>`)",
|
|
27
|
+
},
|
|
28
|
+
jsx: { title: "JSX", description: "JSX/TSX syntax (<div>...</div>)" },
|
|
29
|
+
vue: { title: "Vue", description: "Vue SFC-style templates" },
|
|
30
|
+
}
|
|
31
|
+
|
|
3
32
|
export const THEMES = {
|
|
4
33
|
inglorious: { title: "Inglorious", description: "Neon, videogame-inspired" },
|
|
5
34
|
material: { title: "Material", description: "Material Design inspired" },
|
package/bin/lib/pwa.js
CHANGED
|
@@ -93,7 +93,9 @@ export function writePwaRegistration(targetDir) {
|
|
|
93
93
|
|
|
94
94
|
export function createPwaRegistrationSource(extension) {
|
|
95
95
|
if (extension === ".ts") {
|
|
96
|
-
return
|
|
96
|
+
return `// Only the framework-free helpers: "client" also loads React's and Preact's
|
|
97
|
+
// typings, whose global JSX would replace Inglorious's.
|
|
98
|
+
/// <reference types="vite-plugin-pwa/vanillajs" />
|
|
97
99
|
import { isNative } from "@inglorious/web/mobile"
|
|
98
100
|
import { registerSW } from "virtual:pwa-register"
|
|
99
101
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/create-app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A scaffolding tool to quickly create a new app with Inglorious Web.",
|
|
5
5
|
"author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"prompts": "^2.4.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@inglorious/eslint-config": "1.1.
|
|
40
|
+
"@inglorious/eslint-config": "1.1.4",
|
|
41
41
|
"prettier": "^3.9.6"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { html } from "@inglorious/web"
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { AboutType } from "../../types"
|
|
4
4
|
|
|
5
|
-
export const About = {
|
|
6
|
-
click(entity
|
|
5
|
+
export const About: AboutType = {
|
|
6
|
+
click(entity) {
|
|
7
7
|
entity.name += "!"
|
|
8
8
|
},
|
|
9
9
|
|
|
10
|
-
render(entity
|
|
10
|
+
render(entity, api) {
|
|
11
11
|
return html`
|
|
12
12
|
<div>
|
|
13
13
|
<h1>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { BaseEntity, EntitiesState } from "@inglorious/store"
|
|
1
|
+
import type { BaseEntity, EntitiesState, EntityType } from "@inglorious/store"
|
|
2
|
+
import type { Api, TemplateResult } from "@inglorious/web"
|
|
2
3
|
|
|
3
4
|
// Define your entity types
|
|
4
5
|
export interface AboutEntity extends BaseEntity {
|
|
5
6
|
type: "About"
|
|
6
|
-
id?: string
|
|
7
7
|
name: string
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -15,9 +15,15 @@ export interface AppState extends EntitiesState<AppEntity> {
|
|
|
15
15
|
about: AboutEntity
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
export type AppApi = Api<AppEntity, AppState>
|
|
19
|
+
|
|
20
|
+
// Each type's events and their payloads. Declare types with `type`, not
|
|
21
|
+
// `interface`: an interface does not fit the store's `types`.
|
|
22
|
+
export type AboutType = {
|
|
23
|
+
click: (entity: AboutEntity) => void
|
|
24
|
+
render: (entity: AboutEntity, api: AppApi) => TemplateResult
|
|
23
25
|
}
|
|
26
|
+
|
|
27
|
+
// A shorthand for a type: `{ ... } satisfies AppType<AboutEntity>` infers
|
|
28
|
+
// its handlers' parameters, but neither lists its events nor types payloads.
|
|
29
|
+
export type AppType<TEntity extends AppEntity> = EntityType<TEntity, AppApi>
|
|
@@ -21,13 +21,14 @@
|
|
|
21
21
|
"@inglorious/eslint-config": "workspace:*",
|
|
22
22
|
"@inglorious/vite-plugin-hmr": "workspace:*",
|
|
23
23
|
"@types/node": "^22.20.5",
|
|
24
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
24
25
|
"eslint": "^10.13.0",
|
|
25
26
|
"jiti": "^2.7.0",
|
|
26
27
|
"prettier": "^3.9.10",
|
|
27
28
|
"rollup-plugin-minify-template-literals": "^2.2.0",
|
|
28
29
|
"sharp": "^0.35.5",
|
|
29
30
|
"svgo": "^4.1.0",
|
|
30
|
-
"typescript": "
|
|
31
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
31
32
|
"vite": "^8.3.4",
|
|
32
33
|
"vite-plugin-image-optimizer": "^2.0.3"
|
|
33
34
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createStore
|
|
1
|
+
import { createStore } from "@inglorious/store"
|
|
2
2
|
|
|
3
3
|
import type { AppEntity, AppState } from "../../types"
|
|
4
4
|
import { Message } from "../types/message"
|
|
@@ -6,7 +6,7 @@ import { entities } from "./entities"
|
|
|
6
6
|
import { middlewares } from "./middlewares"
|
|
7
7
|
|
|
8
8
|
export const store = createStore<AppEntity, AppState>({
|
|
9
|
-
types: { Message }
|
|
9
|
+
types: { Message },
|
|
10
10
|
entities,
|
|
11
11
|
middlewares,
|
|
12
12
|
})
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import "./vite-end"
|
|
2
2
|
|
|
3
|
-
import { BaseEntity, EntitiesState } from "@inglorious/store"
|
|
4
|
-
import { Api, TemplateResult } from "@inglorious/web"
|
|
3
|
+
import type { BaseEntity, EntitiesState, EntityType } from "@inglorious/store"
|
|
4
|
+
import type { Api, TemplateResult } from "@inglorious/web"
|
|
5
5
|
|
|
6
6
|
// Define your entity types
|
|
7
7
|
export interface MessageEntity extends BaseEntity {
|
|
8
8
|
type: "Message"
|
|
9
|
-
id?: string
|
|
10
9
|
who: string
|
|
11
10
|
isUpperCase?: boolean
|
|
12
11
|
}
|
|
@@ -23,8 +22,13 @@ export interface AppState extends EntitiesState<AppEntity> {
|
|
|
23
22
|
|
|
24
23
|
export type AppApi = Api<AppEntity, AppState>
|
|
25
24
|
|
|
26
|
-
//
|
|
27
|
-
|
|
25
|
+
// Each type's events and their payloads. Declare types with `type`, not
|
|
26
|
+
// `interface`: an interface does not fit the store's `types`.
|
|
27
|
+
export type MessageType = {
|
|
28
28
|
click: (entity: MessageEntity) => void
|
|
29
|
-
render: (entity: MessageEntity, api: AppApi) => TemplateResult
|
|
29
|
+
render: (entity: MessageEntity, api: AppApi) => TemplateResult
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
// A shorthand for a type: `{ ... } satisfies AppType<MessageEntity>` infers
|
|
33
|
+
// its handlers' parameters, but neither lists its events nor types payloads.
|
|
34
|
+
export type AppType<TEntity extends AppEntity> = EntityType<TEntity, AppApi>
|
|
@@ -23,13 +23,14 @@
|
|
|
23
23
|
"@inglorious/vite-plugin-hmr": "workspace:*",
|
|
24
24
|
"@inglorious/vite-plugin-jsx": "workspace:*",
|
|
25
25
|
"@types/node": "^22.20.5",
|
|
26
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
26
27
|
"eslint": "^10.13.0",
|
|
27
28
|
"jiti": "^2.7.0",
|
|
28
29
|
"prettier": "^3.9.10",
|
|
29
30
|
"rollup-plugin-minify-template-literals": "^2.2.0",
|
|
30
31
|
"sharp": "^0.35.5",
|
|
31
32
|
"svgo": "^4.1.0",
|
|
32
|
-
"typescript": "
|
|
33
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
33
34
|
"vite": "^8.3.4",
|
|
34
35
|
"vite-plugin-image-optimizer": "^2.0.3"
|
|
35
36
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createStore
|
|
1
|
+
import { createStore } from "@inglorious/store"
|
|
2
2
|
|
|
3
3
|
import type { AppEntity, AppState } from "../../types"
|
|
4
4
|
import { Message } from "../types/message"
|
|
@@ -6,7 +6,7 @@ import { entities } from "./entities"
|
|
|
6
6
|
import { middlewares } from "./middlewares"
|
|
7
7
|
|
|
8
8
|
export const store = createStore<AppEntity, AppState>({
|
|
9
|
-
types: { Message }
|
|
9
|
+
types: { Message },
|
|
10
10
|
entities,
|
|
11
11
|
middlewares,
|
|
12
12
|
})
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import "./vite-end"
|
|
2
2
|
|
|
3
|
-
import { BaseEntity, EntitiesState } from "@inglorious/store"
|
|
4
|
-
import { Api, TemplateResult } from "@inglorious/web"
|
|
3
|
+
import type { BaseEntity, EntitiesState, EntityType } from "@inglorious/store"
|
|
4
|
+
import type { Api, TemplateResult } from "@inglorious/web"
|
|
5
5
|
|
|
6
6
|
// Define your entity types
|
|
7
7
|
export interface MessageEntity extends BaseEntity {
|
|
8
8
|
type: "Message"
|
|
9
|
-
id?: string
|
|
10
9
|
who: string
|
|
11
10
|
isUpperCase?: boolean
|
|
12
11
|
}
|
|
@@ -23,8 +22,13 @@ export interface AppState extends EntitiesState<AppEntity> {
|
|
|
23
22
|
|
|
24
23
|
export type AppApi = Api<AppEntity, AppState>
|
|
25
24
|
|
|
26
|
-
//
|
|
27
|
-
|
|
25
|
+
// Each type's events and their payloads. Declare types with `type`, not
|
|
26
|
+
// `interface`: an interface does not fit the store's `types`.
|
|
27
|
+
export type MessageType = {
|
|
28
28
|
click: (entity: MessageEntity) => void
|
|
29
|
-
render: (entity: MessageEntity, api: AppApi) => TemplateResult
|
|
29
|
+
render: (entity: MessageEntity, api: AppApi) => TemplateResult
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
// A shorthand for a type: `{ ... } satisfies AppType<MessageEntity>` infers
|
|
33
|
+
// its handlers' parameters, but neither lists its events nor types payloads.
|
|
34
|
+
export type AppType<TEntity extends AppEntity> = EntityType<TEntity, AppApi>
|
|
@@ -22,13 +22,14 @@
|
|
|
22
22
|
"@inglorious/vite-plugin-hmr": "workspace:*",
|
|
23
23
|
"@inglorious/vite-plugin-vue": "workspace:*",
|
|
24
24
|
"@types/node": "^22.20.5",
|
|
25
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
25
26
|
"eslint": "^10.13.0",
|
|
26
27
|
"jiti": "^2.7.0",
|
|
27
28
|
"prettier": "^3.9.10",
|
|
28
29
|
"rollup-plugin-minify-template-literals": "^2.2.0",
|
|
29
30
|
"sharp": "^0.35.5",
|
|
30
31
|
"svgo": "^4.1.0",
|
|
31
|
-
"typescript": "
|
|
32
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
32
33
|
"vite": "^8.3.4",
|
|
33
34
|
"vite-plugin-image-optimizer": "^2.0.3"
|
|
34
35
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createStore
|
|
1
|
+
import { createStore } from "@inglorious/store"
|
|
2
2
|
|
|
3
3
|
import type { AppEntity, AppState } from "../../types"
|
|
4
4
|
// @ts-expect-error - Handled by @inglorious/vite-plugin-vue
|
|
@@ -7,7 +7,7 @@ import { entities } from "./entities"
|
|
|
7
7
|
import { middlewares } from "./middlewares"
|
|
8
8
|
|
|
9
9
|
export const store = createStore<AppEntity, AppState>({
|
|
10
|
-
types: { Message }
|
|
10
|
+
types: { Message },
|
|
11
11
|
entities,
|
|
12
12
|
middlewares,
|
|
13
13
|
})
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import "./vite-end"
|
|
2
2
|
|
|
3
|
-
import { BaseEntity, EntitiesState } from "@inglorious/store"
|
|
4
|
-
import { Api
|
|
3
|
+
import type { BaseEntity, EntitiesState, EntityType } from "@inglorious/store"
|
|
4
|
+
import type { Api } from "@inglorious/web"
|
|
5
5
|
|
|
6
6
|
// Define your entity types
|
|
7
7
|
export interface MessageEntity extends BaseEntity {
|
|
8
8
|
type: "Message"
|
|
9
|
-
id?: string
|
|
10
9
|
who: string
|
|
11
10
|
isUpperCase?: boolean
|
|
12
11
|
}
|
|
@@ -23,8 +22,7 @@ export interface AppState extends EntitiesState<AppEntity> {
|
|
|
23
22
|
|
|
24
23
|
export type AppApi = Api<AppEntity, AppState>
|
|
25
24
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
25
|
+
// A type for one of the app's entities. For rigour, declare a type alias
|
|
26
|
+
// listing its events and payloads; this shorthand infers its handlers'
|
|
27
|
+
// parameters with `{ ... } satisfies AppType<MessageEntity>`.
|
|
28
|
+
export type AppType<TEntity extends AppEntity> = EntityType<TEntity, AppApi>
|