types-nora-api 0.0.473 → 0.0.474

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.
@@ -1,6 +1,57 @@
1
1
  import type { CtxAcesso } from '../acessos';
2
- import type { PaginaDef, PaginaTemplate, ParamsProps } from '../dtos';
2
+ import type { LayoutContextualizadoInicial } from '../dtos';
3
3
  import type { AcessoPagina } from '../shared';
4
+ type Brand<T, B extends string> = T & {
5
+ readonly __brand: B;
6
+ };
7
+ type ParamSingle = string | number;
8
+ type ParamMany = (string | number)[];
9
+ type ParamValue = ParamSingle | ParamMany | undefined;
10
+ type ParamsRecord = Record<string, ParamValue>;
11
+ type ExtrairParamsDoTemplate<S extends string, Acc extends ParamsRecord = {}> = S extends `${infer _A}[[...${infer P}]]${infer Rest}` ? ExtrairParamsDoTemplate<Rest, Acc & {
12
+ [K in P]?: ParamMany;
13
+ }> : S extends `${infer _A}[...${infer P}]${infer Rest}` ? ExtrairParamsDoTemplate<Rest, Acc & {
14
+ [K in P]: ParamMany;
15
+ }> : S extends `${infer _A}[${infer P}]${infer Rest}` ? ExtrairParamsDoTemplate<Rest, Acc & {
16
+ [K in P]: ParamSingle;
17
+ }> : Acc;
18
+ type PaginaParamsDoTemplate<T extends string> = ExtrairParamsDoTemplate<T>;
19
+ type PaginaInfoBase = {
20
+ readonly label: string;
21
+ readonly comCabecalho?: true;
22
+ readonly acesso?: AcessoPagina;
23
+ readonly acessoPorMenuInterno?: true;
24
+ };
25
+ type PaginaInfoComLayoutContextualizado = PaginaInfoBase & {
26
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
27
+ };
28
+ type PaginaInfo = PaginaInfoBase | PaginaInfoComLayoutContextualizado;
29
+ type PaginaTemplate<T extends string = string> = Brand<T, 'PaginaTemplate'>;
30
+ type PaginaDef<T extends string, I extends PaginaInfo = PaginaInfo> = I & {
31
+ readonly template: PaginaTemplate<T>;
32
+ readonly hrefTemplate: T;
33
+ readonly href: T;
34
+ };
35
+ type PaginaParams<P extends {
36
+ hrefTemplate: string;
37
+ }> = PaginaParamsDoTemplate<P['hrefTemplate']>;
38
+ declare function montarHref(template: string, params: ParamsRecord): string;
39
+ type LimparUndefinedValue = string | number | boolean | object | null | undefined;
40
+ type LimparUndefinedRecord = Record<string, LimparUndefinedValue>;
41
+ declare function limparUndefined<T extends LimparUndefinedRecord>(obj: T): T;
42
+ declare function pagina<const T extends string>(hrefTemplate: T, info: PaginaInfoBase): PaginaDef<T, PaginaInfoBase>;
43
+ declare function paginaComLayoutContextualizado<const T extends string>(hrefTemplate: T, info: PaginaInfoBase, layoutContextualizadoInicial: LayoutContextualizadoInicial): PaginaDef<T, PaginaInfoComLayoutContextualizado>;
44
+ type RequiredKeys<T> = {
45
+ [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
46
+ }[keyof T];
47
+ type ParamsProps<P extends PaginaDef<string>> = keyof PaginaParams<P> extends never ? {
48
+ params?: never;
49
+ } : RequiredKeys<PaginaParams<P>> extends never ? {
50
+ params?: PaginaParams<P>;
51
+ } : {
52
+ params: PaginaParams<P>;
53
+ };
54
+ declare function toParamsRecord(params: object): ParamsRecord;
4
55
  type DecisaoAcessoPagina = {
5
56
  permitido: true;
6
57
  } | {
@@ -21,120 +72,120 @@ type Opts = {
21
72
  declare function decidirAcessoPagina(pagina: PaginaFolha, ctx: CtxAcesso, opts: Opts): DecisaoAcessoPagina;
22
73
  declare function decidirAcessoPagina_Rec(pagina: PaginaFolha, ctx: CtxAcesso, opts: Opts, visitados: Set<string>): DecisaoAcessoPagina;
23
74
  declare const PAGINAS: {
24
- readonly home: PaginaDef<"/", import("../dtos").PaginaInfoBase>;
25
- readonly acessar: PaginaDef<"/acessar", import("../dtos").PaginaInfoBase>;
26
- readonly cadastrar: PaginaDef<"/cadastrar", import("../dtos").PaginaInfoBase>;
27
- readonly definicoes: PaginaDef<"/definicoes/[[...slug]]", import("../dtos").PaginaInfoBase>;
28
- readonly dicas: PaginaDef<"/dicas/[[...slug]]", import("../dtos").PaginaInfoBase>;
75
+ readonly home: PaginaDef<"/", PaginaInfoBase>;
76
+ readonly acessar: PaginaDef<"/acessar", PaginaInfoBase>;
77
+ readonly cadastrar: PaginaDef<"/cadastrar", PaginaInfoBase>;
78
+ readonly definicoes: PaginaDef<"/definicoes/[[...slug]]", PaginaInfoBase>;
79
+ readonly dicas: PaginaDef<"/dicas/[[...slug]]", PaginaInfoBase>;
29
80
  readonly jogo: {
30
81
  readonly admin: {
31
- readonly gerenciarSalas: PaginaDef<"/jogo/admin/gerenciar-salas", import("../dtos").PaginaInfoComLayoutContextualizado>;
82
+ readonly gerenciarSalas: PaginaDef<"/jogo/admin/gerenciar-salas", PaginaInfoComLayoutContextualizado>;
32
83
  };
33
84
  readonly mestre: {
34
- readonly sessoesMestre: PaginaDef<"/jogo/mestre/sessoes-mestre", import("../dtos").PaginaInfoComLayoutContextualizado>;
85
+ readonly sessoesMestre: PaginaDef<"/jogo/mestre/sessoes-mestre", PaginaInfoComLayoutContextualizado>;
35
86
  };
36
- readonly jogador: PaginaDef<"/jogo/jogador", import("../dtos").PaginaInfoComLayoutContextualizado>;
37
- readonly emJogo: PaginaDef<"/jogo/em-jogo", import("../dtos").PaginaInfoBase>;
87
+ readonly jogador: PaginaDef<"/jogo/jogador", PaginaInfoComLayoutContextualizado>;
88
+ readonly emJogo: PaginaDef<"/jogo/em-jogo", PaginaInfoBase>;
38
89
  };
39
- readonly linhaDoTempo: PaginaDef<"/linha-do-tempo", import("../dtos").PaginaInfoBase>;
40
- readonly minhaPagina: PaginaDef<"/minha-pagina", import("../dtos").PaginaInfoBase>;
90
+ readonly linhaDoTempo: PaginaDef<"/linha-do-tempo", PaginaInfoBase>;
91
+ readonly minhaPagina: PaginaDef<"/minha-pagina", PaginaInfoBase>;
41
92
  readonly minhasPaginas: {
42
93
  readonly admin: {
43
- readonly aventura: PaginaDef<"/minhas-paginas/admin/aventura/[id]", import("../dtos").PaginaInfoComLayoutContextualizado>;
44
- readonly aventuras: PaginaDef<"/minhas-paginas/admin/aventuras", import("../dtos").PaginaInfoComLayoutContextualizado>;
45
- readonly dashboardWs: PaginaDef<"/minhas-paginas/admin/dashboard-ws", import("../dtos").PaginaInfoComLayoutContextualizado>;
46
- readonly sessao: PaginaDef<"/minhas-paginas/admin/sessao/[id]", import("../dtos").PaginaInfoComLayoutContextualizado>;
47
- readonly variaveisAmbiente: PaginaDef<"/minhas-paginas/admin/variaveis-ambiente", import("../dtos").PaginaInfoComLayoutContextualizado>;
48
- readonly dashboardPermissoes: PaginaDef<"/minhas-paginas/admin/permissoes", import("../dtos").PaginaInfoComLayoutContextualizado>;
49
- readonly dashboardPermissoesUsuarios: PaginaDef<"/minhas-paginas/admin/permissoes-usuarios", import("../dtos").PaginaInfoComLayoutContextualizado>;
50
- readonly deletarArquivosAbsoluto: PaginaDef<"/minhas-paginas/admin/deletar-arquivos-absoluto", import("../dtos").PaginaInfoComLayoutContextualizado>;
51
- readonly deletarArquivosFileServer: PaginaDef<"/minhas-paginas/admin/deletar-arquivos-file-server", import("../dtos").PaginaInfoComLayoutContextualizado>;
52
- readonly uploadRecursosInternos: PaginaDef<"/minhas-paginas/admin/uploads-recursos-internos", import("../dtos").PaginaInfoComLayoutContextualizado>;
94
+ readonly aventura: PaginaDef<"/minhas-paginas/admin/aventura/[id]", PaginaInfoComLayoutContextualizado>;
95
+ readonly aventuras: PaginaDef<"/minhas-paginas/admin/aventuras", PaginaInfoComLayoutContextualizado>;
96
+ readonly dashboardWs: PaginaDef<"/minhas-paginas/admin/dashboard-ws", PaginaInfoComLayoutContextualizado>;
97
+ readonly sessao: PaginaDef<"/minhas-paginas/admin/sessao/[id]", PaginaInfoComLayoutContextualizado>;
98
+ readonly variaveisAmbiente: PaginaDef<"/minhas-paginas/admin/variaveis-ambiente", PaginaInfoComLayoutContextualizado>;
99
+ readonly dashboardPermissoes: PaginaDef<"/minhas-paginas/admin/permissoes", PaginaInfoComLayoutContextualizado>;
100
+ readonly dashboardPermissoesUsuarios: PaginaDef<"/minhas-paginas/admin/permissoes-usuarios", PaginaInfoComLayoutContextualizado>;
101
+ readonly deletarArquivosAbsoluto: PaginaDef<"/minhas-paginas/admin/deletar-arquivos-absoluto", PaginaInfoComLayoutContextualizado>;
102
+ readonly deletarArquivosFileServer: PaginaDef<"/minhas-paginas/admin/deletar-arquivos-file-server", PaginaInfoComLayoutContextualizado>;
103
+ readonly uploadRecursosInternos: PaginaDef<"/minhas-paginas/admin/uploads-recursos-internos", PaginaInfoComLayoutContextualizado>;
53
104
  readonly label: string;
54
105
  readonly comCabecalho?: true;
55
106
  readonly acesso?: AcessoPagina;
56
107
  readonly acessoPorMenuInterno?: true;
57
- readonly layoutContextualizadoInicial: import("../dtos").LayoutContextualizadoInicial;
108
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
58
109
  readonly template: PaginaTemplate<"/minhas-paginas/admin">;
59
110
  readonly hrefTemplate: "/minhas-paginas/admin";
60
111
  readonly href: "/minhas-paginas/admin";
61
112
  };
62
113
  readonly moderador: {
63
- readonly dashboardAprovacaoImagensArtista: PaginaDef<"/minhas-paginas/moderador/aprovar-imagens-artista", import("../dtos").PaginaInfoComLayoutContextualizado>;
114
+ readonly dashboardAprovacaoImagensArtista: PaginaDef<"/minhas-paginas/moderador/aprovar-imagens-artista", PaginaInfoComLayoutContextualizado>;
64
115
  readonly label: string;
65
116
  readonly comCabecalho?: true;
66
117
  readonly acesso?: AcessoPagina;
67
118
  readonly acessoPorMenuInterno?: true;
68
- readonly layoutContextualizadoInicial: import("../dtos").LayoutContextualizadoInicial;
119
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
69
120
  readonly template: PaginaTemplate<"/minhas-paginas/moderador">;
70
121
  readonly hrefTemplate: "/minhas-paginas/moderador";
71
122
  readonly href: "/minhas-paginas/moderador";
72
123
  };
73
124
  readonly mestre: {
74
- readonly aventura: PaginaDef<"/minhas-paginas/mestre/aventura/[id]", import("../dtos").PaginaInfoComLayoutContextualizado>;
75
- readonly aventuras: PaginaDef<"/minhas-paginas/mestre/aventuras", import("../dtos").PaginaInfoComLayoutContextualizado>;
76
- readonly sessoesUnicas: PaginaDef<"/minhas-paginas/mestre/sessoes-unicas", import("../dtos").PaginaInfoComLayoutContextualizado>;
77
- readonly personagens: PaginaDef<"/minhas-paginas/mestre/personagens", import("../dtos").PaginaInfoComLayoutContextualizado>;
125
+ readonly aventura: PaginaDef<"/minhas-paginas/mestre/aventura/[id]", PaginaInfoComLayoutContextualizado>;
126
+ readonly aventuras: PaginaDef<"/minhas-paginas/mestre/aventuras", PaginaInfoComLayoutContextualizado>;
127
+ readonly sessoesUnicas: PaginaDef<"/minhas-paginas/mestre/sessoes-unicas", PaginaInfoComLayoutContextualizado>;
128
+ readonly personagens: PaginaDef<"/minhas-paginas/mestre/personagens", PaginaInfoComLayoutContextualizado>;
78
129
  readonly rascunhos: {
79
- readonly aventuras: PaginaDef<"/minhas-paginas/mestre/rascunhos/aventuras", import("../dtos").PaginaInfoComLayoutContextualizado>;
80
- readonly sessoesUnicas: PaginaDef<"/minhas-paginas/mestre/rascunhos/sessoes-unicas", import("../dtos").PaginaInfoComLayoutContextualizado>;
130
+ readonly aventuras: PaginaDef<"/minhas-paginas/mestre/rascunhos/aventuras", PaginaInfoComLayoutContextualizado>;
131
+ readonly sessoesUnicas: PaginaDef<"/minhas-paginas/mestre/rascunhos/sessoes-unicas", PaginaInfoComLayoutContextualizado>;
81
132
  };
82
133
  readonly temporario: {
83
- readonly consultarDisponibilidades: PaginaDef<"/minhas-paginas/mestre/consultar-disponibilidades", import("../dtos").PaginaInfoComLayoutContextualizado>;
84
- readonly criarSessaoUnica: PaginaDef<"/minhas-paginas/mestre/criar-sessao-unica", import("../dtos").PaginaInfoComLayoutContextualizado>;
134
+ readonly consultarDisponibilidades: PaginaDef<"/minhas-paginas/mestre/consultar-disponibilidades", PaginaInfoComLayoutContextualizado>;
135
+ readonly criarSessaoUnica: PaginaDef<"/minhas-paginas/mestre/criar-sessao-unica", PaginaInfoComLayoutContextualizado>;
85
136
  };
86
- readonly sessao: PaginaDef<"/minhas-paginas/mestre/sessao/[id]", import("../dtos").PaginaInfoComLayoutContextualizado>;
137
+ readonly sessao: PaginaDef<"/minhas-paginas/mestre/sessao/[id]", PaginaInfoComLayoutContextualizado>;
87
138
  readonly label: string;
88
139
  readonly comCabecalho?: true;
89
140
  readonly acesso?: AcessoPagina;
90
141
  readonly acessoPorMenuInterno?: true;
91
- readonly layoutContextualizadoInicial: import("../dtos").LayoutContextualizadoInicial;
142
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
92
143
  readonly template: PaginaTemplate<"/minhas-paginas/mestre">;
93
144
  readonly hrefTemplate: "/minhas-paginas/mestre";
94
145
  readonly href: "/minhas-paginas/mestre";
95
146
  };
96
147
  readonly artista: {
97
- readonly minhasImagens: PaginaDef<"/minhas-paginas/artista/minhas-imagens", import("../dtos").PaginaInfoComLayoutContextualizado>;
98
- readonly adicionarImagem: PaginaDef<"/minhas-paginas/artista/adicionar-imagem", import("../dtos").PaginaInfoComLayoutContextualizado>;
148
+ readonly minhasImagens: PaginaDef<"/minhas-paginas/artista/minhas-imagens", PaginaInfoComLayoutContextualizado>;
149
+ readonly adicionarImagem: PaginaDef<"/minhas-paginas/artista/adicionar-imagem", PaginaInfoComLayoutContextualizado>;
99
150
  readonly avatares: {
100
- readonly gerenciarAvatares: PaginaDef<"/minhas-paginas/artista/avatares", import("../dtos").PaginaInfoComLayoutContextualizado>;
151
+ readonly gerenciarAvatares: PaginaDef<"/minhas-paginas/artista/avatares", PaginaInfoComLayoutContextualizado>;
101
152
  };
102
153
  readonly emblemas: {
103
- readonly gerenciarEmblemas: PaginaDef<"/minhas-paginas/artista/emblemas", import("../dtos").PaginaInfoComLayoutContextualizado>;
154
+ readonly gerenciarEmblemas: PaginaDef<"/minhas-paginas/artista/emblemas", PaginaInfoComLayoutContextualizado>;
104
155
  };
105
156
  readonly label: string;
106
157
  readonly comCabecalho?: true;
107
158
  readonly acesso?: AcessoPagina;
108
159
  readonly acessoPorMenuInterno?: true;
109
- readonly layoutContextualizadoInicial: import("../dtos").LayoutContextualizadoInicial;
160
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
110
161
  readonly template: PaginaTemplate<"/minhas-paginas/artista">;
111
162
  readonly hrefTemplate: "/minhas-paginas/artista";
112
163
  readonly href: "/minhas-paginas/artista";
113
164
  };
114
165
  readonly jogador: {
115
- readonly meusPersonagens: PaginaDef<"/minhas-paginas/jogador/meus-personagens", import("../dtos").PaginaInfoComLayoutContextualizado>;
116
- readonly minhasFichas: PaginaDef<"/minhas-paginas/jogador/minhas-fichas", import("../dtos").PaginaInfoComLayoutContextualizado>;
166
+ readonly meusPersonagens: PaginaDef<"/minhas-paginas/jogador/meus-personagens", PaginaInfoComLayoutContextualizado>;
167
+ readonly minhasFichas: PaginaDef<"/minhas-paginas/jogador/minhas-fichas", PaginaInfoComLayoutContextualizado>;
117
168
  readonly criar: {
118
- readonly ficha: PaginaDef<"/minhas-paginas/jogador/criar/ficha", import("../dtos").PaginaInfoComLayoutContextualizado>;
119
- readonly personagem: PaginaDef<"/minhas-paginas/jogador/criar/personagem", import("../dtos").PaginaInfoComLayoutContextualizado>;
169
+ readonly ficha: PaginaDef<"/minhas-paginas/jogador/criar/ficha", PaginaInfoComLayoutContextualizado>;
170
+ readonly personagem: PaginaDef<"/minhas-paginas/jogador/criar/personagem", PaginaInfoComLayoutContextualizado>;
120
171
  };
121
172
  readonly label: string;
122
173
  readonly comCabecalho?: true;
123
174
  readonly acesso?: AcessoPagina;
124
175
  readonly acessoPorMenuInterno?: true;
125
- readonly layoutContextualizadoInicial: import("../dtos").LayoutContextualizadoInicial;
176
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
126
177
  readonly template: PaginaTemplate<"/minhas-paginas/jogador">;
127
178
  readonly hrefTemplate: "/minhas-paginas/jogador";
128
179
  readonly href: "/minhas-paginas/jogador";
129
180
  };
130
- readonly minhasDisponibilidades: PaginaDef<"/minhas-paginas/minhas-disponibilidades", import("../dtos").PaginaInfoComLayoutContextualizado>;
181
+ readonly minhasDisponibilidades: PaginaDef<"/minhas-paginas/minhas-disponibilidades", PaginaInfoComLayoutContextualizado>;
131
182
  readonly minhasConfiguracoes: {
132
- readonly passeDeJogador: PaginaDef<"/minhas-paginas/minhas-configuracoes/passe-de-jogador", import("../dtos").PaginaInfoComLayoutContextualizado>;
183
+ readonly passeDeJogador: PaginaDef<"/minhas-paginas/minhas-configuracoes/passe-de-jogador", PaginaInfoComLayoutContextualizado>;
133
184
  readonly label: string;
134
185
  readonly comCabecalho?: true;
135
186
  readonly acesso?: AcessoPagina;
136
187
  readonly acessoPorMenuInterno?: true;
137
- readonly layoutContextualizadoInicial: import("../dtos").LayoutContextualizadoInicial;
188
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
138
189
  readonly template: PaginaTemplate<"/minhas-paginas/minhas-configuracoes">;
139
190
  readonly hrefTemplate: "/minhas-paginas/minhas-configuracoes";
140
191
  readonly href: "/minhas-paginas/minhas-configuracoes";
@@ -143,16 +194,16 @@ declare const PAGINAS: {
143
194
  readonly comCabecalho?: true;
144
195
  readonly acesso?: AcessoPagina;
145
196
  readonly acessoPorMenuInterno?: true;
146
- readonly layoutContextualizadoInicial: import("../dtos").LayoutContextualizadoInicial;
197
+ readonly layoutContextualizadoInicial: LayoutContextualizadoInicial;
147
198
  readonly template: PaginaTemplate<"/minhas-paginas">;
148
199
  readonly hrefTemplate: "/minhas-paginas";
149
200
  readonly href: "/minhas-paginas";
150
201
  };
151
- readonly fichas: PaginaDef<"/fichas", import("../dtos").PaginaInfoComLayoutContextualizado>;
152
- readonly personagens: PaginaDef<"/personagens", import("../dtos").PaginaInfoComLayoutContextualizado>;
153
- readonly sessoes: PaginaDef<"/sessoes", import("../dtos").PaginaInfoComLayoutContextualizado>;
154
- readonly sessaoAovivo: PaginaDef<"/sessao-aovivo", import("../dtos").PaginaInfoBase>;
155
- readonly assistir: PaginaDef<"/assistir", import("../dtos").PaginaInfoComLayoutContextualizado>;
202
+ readonly fichas: PaginaDef<"/fichas", PaginaInfoComLayoutContextualizado>;
203
+ readonly personagens: PaginaDef<"/personagens", PaginaInfoComLayoutContextualizado>;
204
+ readonly sessoes: PaginaDef<"/sessoes", PaginaInfoComLayoutContextualizado>;
205
+ readonly sessaoAovivo: PaginaDef<"/sessao-aovivo", PaginaInfoBase>;
206
+ readonly assistir: PaginaDef<"/assistir", PaginaInfoComLayoutContextualizado>;
156
207
  };
157
208
  type Folhas<T> = T extends PaginaDef<string> ? T | Folhas<Omit<T, keyof PaginaDef<string>>> : T extends readonly (infer U)[] ? Folhas<U> : T extends object ? {
158
209
  [K in keyof T]-?: Folhas<NonNullable<T[K]>>;
@@ -169,4 +220,4 @@ type PaginaHrefTemplate = PaginaFolha['hrefTemplate'];
169
220
  type PaginaHref = PaginaFolha['href'];
170
221
  type PaginaDefAny = PaginaDef<string>;
171
222
  type PaginaTemplateAny = PaginaTemplate<string>;
172
- export { DecisaoAcessoPagina, Folhas, Opts, PAGINAS, PaginaDefAny, PaginaDestino, PaginaDestinoPagina, PaginaFolha, PaginaHref, PaginaHrefTemplate, PaginaTemplateAny, PaginaTemplateFolha, ResolverMenuInterno, decidirAcessoPagina, decidirAcessoPagina_Rec };
223
+ export { Brand, DecisaoAcessoPagina, ExtrairParamsDoTemplate, Folhas, LimparUndefinedRecord, LimparUndefinedValue, Opts, PAGINAS, PaginaDef, PaginaDefAny, PaginaDestino, PaginaDestinoPagina, PaginaFolha, PaginaHref, PaginaHrefTemplate, PaginaInfo, PaginaInfoBase, PaginaInfoComLayoutContextualizado, PaginaParams, PaginaParamsDoTemplate, PaginaTemplate, PaginaTemplateAny, PaginaTemplateFolha, ParamMany, ParamSingle, ParamValue, ParamsProps, ParamsRecord, RequiredKeys, ResolverMenuInterno, decidirAcessoPagina, decidirAcessoPagina_Rec, limparUndefined, montarHref, pagina, paginaComLayoutContextualizado, toParamsRecord };
@@ -2,7 +2,60 @@
2
2
  // Contratos de páginas
3
3
  import { temSudoBurlarCapacidades } from '../acessos';
4
4
  import { CAPACIDADES } from '../dominio';
5
- import { pagina, paginaComLayoutContextualizado } from '../dtos';
5
+ function montarHref(template, params) {
6
+ const out = template.replace(/\[\[\.\.\.([^\]]+)\]\]|\[\.\.\.([^\]]+)\]|\[([^\]]+)\]/g, (_m, optCatchAll, catchAll, single) => {
7
+ const key = (optCatchAll || catchAll || single);
8
+ const value = params[key];
9
+ if (optCatchAll) {
10
+ if (value == null)
11
+ return '';
12
+ if (!Array.isArray(value))
13
+ throw new Error(`PAGINAS.montarHref: "${key}" deve ser (string|number)[] (optional catch-all)`);
14
+ return value.map((x) => encodeURIComponent(String(x))).join('/');
15
+ }
16
+ if (catchAll) {
17
+ if (!Array.isArray(value))
18
+ throw new Error(`PAGINAS.montarHref: "${key}" deve ser (string|number)[] (catch-all)`);
19
+ return value.map((x) => encodeURIComponent(String(x))).join('/');
20
+ }
21
+ if (value == null)
22
+ throw new Error(`PAGINAS.montarHref: "${key}" é obrigatório`);
23
+ if (Array.isArray(value))
24
+ throw new Error(`PAGINAS.montarHref: "${key}" deve ser string|number (single param)`);
25
+ return encodeURIComponent(String(value));
26
+ });
27
+ const cleaned = out.replace(/\/+/g, '/').replace(/\/$/, '');
28
+ return cleaned === '' ? '/' : cleaned;
29
+ }
30
+ function limparUndefined(obj) {
31
+ const out = {};
32
+ for (const k in obj) {
33
+ if (!Object.prototype.hasOwnProperty.call(obj, k))
34
+ continue;
35
+ const key = k;
36
+ const v = obj[key];
37
+ if (v !== undefined)
38
+ out[key] = v;
39
+ }
40
+ return out;
41
+ }
42
+ function pagina(hrefTemplate, info) {
43
+ const template = hrefTemplate;
44
+ return limparUndefined({ template, hrefTemplate, href: hrefTemplate, ...info });
45
+ }
46
+ function paginaComLayoutContextualizado(hrefTemplate, info, layoutContextualizadoInicial) {
47
+ const template = hrefTemplate;
48
+ return limparUndefined({ template, hrefTemplate, href: hrefTemplate, ...info, layoutContextualizadoInicial });
49
+ }
50
+ function toParamsRecord(params) {
51
+ const out = {};
52
+ for (const k in params) {
53
+ if (!Object.prototype.hasOwnProperty.call(params, k))
54
+ continue;
55
+ out[k] = params[k];
56
+ }
57
+ return out;
58
+ }
6
59
  /*
7
60
  SSOT: regra de acesso única, usada por:
8
61
  - ControladorSlot (bloqueio/redirect)
@@ -134,4 +187,4 @@ const PAGINAS = {
134
187
  sessaoAovivo: pagina('/sessao-aovivo', { label: 'Sessão Ao Vivo', acesso: { autenticado: true } }),
135
188
  assistir: paginaComLayoutContextualizado('/assistir', { label: 'Assistir' }, { titulo: 'Assistir', proporcaoConteudo: 80 }),
136
189
  };
137
- export { PAGINAS, decidirAcessoPagina, decidirAcessoPagina_Rec };
190
+ export { PAGINAS, decidirAcessoPagina, decidirAcessoPagina_Rec, limparUndefined, montarHref, pagina, paginaComLayoutContextualizado, toParamsRecord };
@@ -1,4 +1,52 @@
1
- import type { FormatoUploadArquivo, RegrasUploadArquivo } from '../dtos';
1
+ type FormatoUploadArquivo = 'png' | 'webp' | 'svg';
2
+ type DimensoesImagem = {
3
+ largura: number;
4
+ altura: number;
5
+ };
6
+ type RequireAtLeastOne<T, K extends keyof T> = Omit<T, K> & {
7
+ [P in K]-?: Required<Pick<T, P>> & Partial<Omit<Pick<T, K>, P>>;
8
+ }[K];
9
+ type RegraTamanhoArquivo = RequireAtLeastOne<{
10
+ minBytes?: number;
11
+ maxBytes?: number;
12
+ }, 'minBytes' | 'maxBytes'>;
13
+ type RegraDimensoesImagem = {
14
+ modo: 'exato';
15
+ exato: DimensoesImagem;
16
+ } | ({
17
+ modo: 'intervalo';
18
+ } & RequireAtLeastOne<{
19
+ min?: DimensoesImagem;
20
+ max?: DimensoesImagem;
21
+ }, 'min' | 'max'>);
22
+ type RegraProporcaoImagem = {
23
+ largura: number;
24
+ altura: number;
25
+ toleranciaPercentual?: number;
26
+ };
27
+ type RegrasUploadBase = {
28
+ formatosPermitidos: FormatoUploadArquivo[];
29
+ tamanho?: RegraTamanhoArquivo;
30
+ };
31
+ type RegrasUploadImagem = RegrasUploadBase & {
32
+ imagem: {
33
+ tipoValidacao: 'dimensoes';
34
+ dimensoes: RegraDimensoesImagem;
35
+ maxPixels?: number;
36
+ } | {
37
+ tipoValidacao: 'proporcao';
38
+ proporcao: RegraProporcaoImagem;
39
+ maxPixels?: number;
40
+ } | {
41
+ tipoValidacao: 'nenhuma';
42
+ maxPixels?: number;
43
+ };
44
+ };
45
+ type RegrasUploadArquivo = RegrasUploadBase | RegrasUploadImagem;
46
+ type ResultadoSaveFile = {
47
+ caminhoArquivo: string;
48
+ tipoMime: string;
49
+ };
2
50
  type ResultadoValidacao = {
3
51
  ok: true;
4
52
  } | {
@@ -44,4 +92,4 @@ declare function isRegrasUploadArquivoValidas(regras: RegrasUploadArquivo): regr
44
92
  declare function mimeFromFormato(formato: FormatoUploadArquivo): string | null;
45
93
  declare function acceptFromFormatos(formatos: FormatoUploadArquivo[]): string;
46
94
  declare function isFormatoImagemBitmap(formato: FormatoUploadArquivo): formato is "png" | "webp";
47
- export { ResultadoValidacao, acceptFromFormatos, isFormatoImagemBitmap, isNumeroInteiroPositivo, isNumeroPositivo, isRegrasUploadArquivoValidas, mimeFromFormato, pushErro, validarDimensoesDim, validarDimensoesRegra, validarFormatos, validarImagem, validarMaxPixels, validarProporcao, validarRegrasUploadArquivo, validarTamanho };
95
+ export { DimensoesImagem, FormatoUploadArquivo, RegraDimensoesImagem, RegraProporcaoImagem, RegraTamanhoArquivo, RegrasUploadArquivo, RegrasUploadBase, RegrasUploadImagem, RequireAtLeastOne, ResultadoSaveFile, ResultadoValidacao, acceptFromFormatos, isFormatoImagemBitmap, isNumeroInteiroPositivo, isNumeroPositivo, isRegrasUploadArquivoValidas, mimeFromFormato, pushErro, validarDimensoesDim, validarDimensoesRegra, validarFormatos, validarImagem, validarMaxPixels, validarProporcao, validarRegrasUploadArquivo, validarTamanho };