@magidoc/plugin-starter-variables 0.9.3 → 0.11.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.
Files changed (34) hide show
  1. package/build/index.d.ts +2 -1
  2. package/build/variables/converters/array.d.ts +2 -0
  3. package/build/variables/converters/array.js +22 -0
  4. package/build/variables/converters/array.js.map +1 -0
  5. package/build/variables/converters/boolean.d.ts +2 -0
  6. package/build/variables/converters/boolean.js +26 -0
  7. package/build/variables/converters/boolean.js.map +1 -0
  8. package/build/variables/converters/index.d.ts +5 -0
  9. package/build/variables/converters/record.d.ts +2 -0
  10. package/build/variables/converters/record.js +22 -0
  11. package/build/variables/converters/record.js.map +1 -0
  12. package/build/variables/converters/string.d.ts +2 -0
  13. package/build/variables/converters/string.js +15 -0
  14. package/build/variables/converters/string.js.map +1 -0
  15. package/build/variables/magidoc.js +3 -2
  16. package/build/variables/magidoc.js.map +1 -1
  17. package/build/variables/templates.d.ts +6 -0
  18. package/build/variables/templates.js +20 -3
  19. package/build/variables/templates.js.map +1 -1
  20. package/build/variables/variable.d.ts +14 -4
  21. package/build/variables/variable.js +8 -31
  22. package/build/variables/variable.js.map +1 -1
  23. package/package.json +4 -1
  24. package/rollup.config.cjs +1 -1
  25. package/src/index.ts +2 -1
  26. package/src/variables/converters/array.ts +25 -0
  27. package/src/variables/converters/boolean.ts +24 -0
  28. package/src/variables/converters/index.ts +6 -0
  29. package/src/variables/converters/record.ts +25 -0
  30. package/src/variables/converters/string.ts +15 -0
  31. package/src/variables/magidoc.ts +3 -2
  32. package/src/variables/templates.ts +39 -3
  33. package/src/variables/variable.ts +27 -34
  34. package/tests/index.spec.ts +171 -12
package/build/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import templates from './variables/templates';
2
2
  import magidoc from './variables/magidoc';
3
3
  import type { Variable, ViteVariable } from './variables/variable';
4
+ import type { Page } from './variables/templates';
4
5
  export { templates };
5
6
  export { magidoc };
6
- export type { Variable, ViteVariable };
7
+ export type { Variable, ViteVariable, Page };
@@ -0,0 +1,2 @@
1
+ import type { Converter, ZodTypeProvider } from '../variable';
2
+ export declare function arrayConverter<V>(valueType: ZodTypeProvider<V>): Converter<Array<V | undefined>>;
@@ -0,0 +1,22 @@
1
+ function arrayConverter(valueType) {
2
+ return {
3
+ convert: (target) => {
4
+ if (Array.isArray(target)) {
5
+ return target;
6
+ }
7
+ if (typeof target === 'string') {
8
+ const result = JSON.parse(target);
9
+ if (!Array.isArray(result)) {
10
+ return null;
11
+ }
12
+ return result;
13
+ }
14
+ return null;
15
+ },
16
+ asString: (value) => JSON.stringify(value),
17
+ type: (z) => z.array(valueType(z)).optional(),
18
+ };
19
+ }
20
+
21
+ export { arrayConverter };
22
+ //# sourceMappingURL=array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.js","sources":["../../../../src/variables/converters/array.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEM,SAAU,cAAc,CAC5B,SAA6B,EAAA;IAE7B,OAAO;AACL,QAAA,OAAO,EAAE,CAAC,MAAM,KAAI;AAClB,YAAA,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;AACzB,gBAAA,OAAO,MAAkB,CAAA;AAC1B,aAAA;AAED,YAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;gBAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAsB,CAAA;AACtD,gBAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;AAC1B,oBAAA,OAAO,IAAI,CAAA;AACZ,iBAAA;AACD,gBAAA,OAAO,MAAM,CAAA;AACd,aAAA;AAED,YAAA,OAAO,IAAI,CAAA;SACZ;QACD,QAAQ,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AAC1C,QAAA,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;KAC9C,CAAA;AACH;;;;"}
@@ -0,0 +1,2 @@
1
+ import type { Converter } from '../variable';
2
+ export declare function booleanConverter(): Converter<boolean>;
@@ -0,0 +1,26 @@
1
+ function booleanConverter() {
2
+ return {
3
+ convert: (target) => {
4
+ if (target === null)
5
+ return null;
6
+ if (target === undefined)
7
+ return null;
8
+ switch (typeof target) {
9
+ case 'boolean':
10
+ return target;
11
+ case 'string':
12
+ const lowerCase = target.toLowerCase().trim();
13
+ return lowerCase === 'true' || lowerCase === 't' || lowerCase === '1';
14
+ case 'number':
15
+ return target !== 0;
16
+ default:
17
+ return null;
18
+ }
19
+ },
20
+ asString: (value) => String(value),
21
+ type: (z) => z.boolean().optional(),
22
+ };
23
+ }
24
+
25
+ export { booleanConverter };
26
+ //# sourceMappingURL=boolean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boolean.js","sources":["../../../../src/variables/converters/boolean.ts"],"sourcesContent":[null],"names":[],"mappings":"SAEgB,gBAAgB,GAAA;IAC9B,OAAO;AACL,QAAA,OAAO,EAAE,CAAC,MAAe,KAAoB;YAC3C,IAAI,MAAM,KAAK,IAAI;AAAE,gBAAA,OAAO,IAAI,CAAA;YAChC,IAAI,MAAM,KAAK,SAAS;AAAE,gBAAA,OAAO,IAAI,CAAA;YAErC,QAAQ,OAAO,MAAM;AACnB,gBAAA,KAAK,SAAS;AACZ,oBAAA,OAAO,MAAM,CAAA;AACf,gBAAA,KAAK,QAAQ;oBACX,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAA;oBAC7C,OAAO,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,GAAG,CAAA;AACvE,gBAAA,KAAK,QAAQ;oBACX,OAAO,MAAM,KAAK,CAAC,CAAA;AACrB,gBAAA;AACE,oBAAA,OAAO,IAAI,CAAA;AACd,aAAA;SACF;QACD,QAAQ,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC;AAClC,QAAA,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;KACpC,CAAA;AACH;;;;"}
@@ -0,0 +1,5 @@
1
+ import { stringConverter } from './string';
2
+ import { booleanConverter } from './boolean';
3
+ import { recordConverter } from './record';
4
+ import { arrayConverter } from './array';
5
+ export { stringConverter, booleanConverter, recordConverter, arrayConverter };
@@ -0,0 +1,2 @@
1
+ import type { Converter, ZodTypeProvider } from '../variable';
2
+ export declare function recordConverter<V>(valueType: ZodTypeProvider<V>): Converter<Record<string, V | undefined>>;
@@ -0,0 +1,22 @@
1
+ function recordConverter(valueType) {
2
+ return {
3
+ convert: (target) => {
4
+ if (typeof target === 'object') {
5
+ return target;
6
+ }
7
+ if (typeof target === 'string') {
8
+ const result = JSON.parse(target);
9
+ if (typeof result !== 'object') {
10
+ return null;
11
+ }
12
+ return result;
13
+ }
14
+ return null;
15
+ },
16
+ asString: (value) => JSON.stringify(value),
17
+ type: (z) => z.record(valueType(z).optional()).optional(),
18
+ };
19
+ }
20
+
21
+ export { recordConverter };
22
+ //# sourceMappingURL=record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.js","sources":["../../../../src/variables/converters/record.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEM,SAAU,eAAe,CAC7B,SAA6B,EAAA;IAE7B,OAAO;AACL,QAAA,OAAO,EAAE,CAAC,MAAM,KAAI;AAClB,YAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,gBAAA,OAAO,MAA2B,CAAA;AACnC,aAAA;AAED,YAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;gBAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAsB,CAAA;AACtD,gBAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,oBAAA,OAAO,IAAI,CAAA;AACZ,iBAAA;AACD,gBAAA,OAAO,MAAM,CAAA;AACd,aAAA;AAED,YAAA,OAAO,IAAI,CAAA;SACZ;QACD,QAAQ,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QAC1C,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;KAC1D,CAAA;AACH;;;;"}
@@ -0,0 +1,2 @@
1
+ import type { Converter } from '../variable';
2
+ export declare function stringConverter(): Converter<string>;
@@ -0,0 +1,15 @@
1
+ function stringConverter() {
2
+ return {
3
+ convert: (target) => {
4
+ if (target === null || target === undefined || target === '') {
5
+ return null;
6
+ }
7
+ return String(target);
8
+ },
9
+ asString: (value) => String(value),
10
+ type: (z) => z.string().optional(),
11
+ };
12
+ }
13
+
14
+ export { stringConverter };
15
+ //# sourceMappingURL=string.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string.js","sources":["../../../../src/variables/converters/string.ts"],"sourcesContent":[null],"names":[],"mappings":"SAEgB,eAAe,GAAA;IAC7B,OAAO;AACL,QAAA,OAAO,EAAE,CAAC,MAAe,KAAmB;YAC1C,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE;AAC5D,gBAAA,OAAO,IAAI,CAAA;AACZ,aAAA;AAED,YAAA,OAAO,MAAM,CAAC,MAAM,CAAC,CAAA;SACtB;QACD,QAAQ,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC;AAClC,QAAA,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACnC,CAAA;AACH;;;;"}
@@ -1,7 +1,8 @@
1
- import { createVariable, booleanConversion } from './variable.js';
1
+ import { booleanConverter } from './converters/boolean.js';
2
+ import { createVariable } from './variable.js';
2
3
 
3
4
  var magidoc = {
4
- MAGIDOC_GENERATE: createVariable('MAGIDOC_GENERATE', booleanConversion()),
5
+ MAGIDOC_GENERATE: createVariable('MAGIDOC_GENERATE', booleanConverter()),
5
6
  };
6
7
 
7
8
  export { magidoc as default };
@@ -1 +1 @@
1
- {"version":3,"file":"magidoc.js","sources":["../../../src/variables/magidoc.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA,cAAe;AACb,IAAA,gBAAgB,EAAE,cAAc,CAC9B,kBAAkB,EAClB,iBAAiB,EAAE,CACpB;CACF;;;;"}
1
+ {"version":3,"file":"magidoc.js","sources":["../../../src/variables/magidoc.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGA,cAAe;AACb,IAAA,gBAAgB,EAAE,cAAc,CAC9B,kBAAkB,EAClB,gBAAgB,EAAE,CACnB;CACF;;;;"}
@@ -1,5 +1,11 @@
1
+ export declare type Page = {
2
+ title: string;
3
+ content: string | Page[];
4
+ };
1
5
  declare const _default: {
2
6
  APP_LOGO: import("./variable").Variable<string>;
3
7
  APP_TITLE: import("./variable").Variable<string>;
8
+ QUERY_GENERATION_FACTORIES: import("./variable").Variable<Record<string, string | number | boolean | Record<string, unknown> | null | undefined>>;
9
+ PAGES: import("./variable").Variable<(Page | undefined)[]>;
4
10
  };
5
11
  export default _default;
@@ -1,8 +1,25 @@
1
- import { createVariable, stringConversion } from './variable.js';
1
+ import { stringConverter } from './converters/string.js';
2
+ import { recordConverter } from './converters/record.js';
3
+ import { arrayConverter } from './converters/array.js';
4
+ import { createVariable } from './variable.js';
2
5
 
3
6
  var templates = {
4
- APP_LOGO: createVariable('APP_LOGO', stringConversion()),
5
- APP_TITLE: createVariable('APP_TITLE', stringConversion()),
7
+ APP_LOGO: createVariable('APP_LOGO', stringConverter()),
8
+ APP_TITLE: createVariable('APP_TITLE', stringConverter()),
9
+ QUERY_GENERATION_FACTORIES: createVariable('QUERY_GENERATION_FACTORIES', recordConverter((zod) => zod.union([
10
+ zod.string(),
11
+ zod.boolean(),
12
+ zod.number(),
13
+ zod.null(),
14
+ zod.record(zod.unknown()),
15
+ ]))),
16
+ PAGES: createVariable('PAGES', arrayConverter((zod) => {
17
+ const type = zod.lazy(() => zod.object({
18
+ title: zod.string().nonempty(),
19
+ content: zod.union([zod.array(type), zod.string().nonempty()]),
20
+ }));
21
+ return type;
22
+ })),
6
23
  };
7
24
 
8
25
  export { templates as default };
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sources":["../../../src/variables/templates.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA,gBAAe;AACb,IAAA,QAAQ,EAAE,cAAc,CAAS,UAAU,EAAE,gBAAgB,EAAE,CAAC;AAChE,IAAA,SAAS,EAAE,cAAc,CAAS,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACnE;;;;"}
1
+ {"version":3,"file":"templates.js","sources":["../../../src/variables/templates.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;AASA,gBAAe;AACb,IAAA,QAAQ,EAAE,cAAc,CAAS,UAAU,EAAE,eAAe,EAAE,CAAC;AAC/D,IAAA,SAAS,EAAE,cAAc,CAAS,WAAW,EAAE,eAAe,EAAE,CAAC;AACjE,IAAA,0BAA0B,EAAE,cAAc,CAMxC,4BAA4B,EAC5B,eAAe,CAAC,CAAC,GAAG,KAClB,GAAG,CAAC,KAAK,CAAC;QACR,GAAG,CAAC,MAAM,EAAE;QACZ,GAAG,CAAC,OAAO,EAAE;QACb,GAAG,CAAC,MAAM,EAAE;QACZ,GAAG,CAAC,IAAI,EAAE;AACV,QAAA,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;AAC1B,KAAA,CAAC,CACH,CACF;IACD,KAAK,EAAE,cAAc,CACnB,OAAO,EACP,cAAc,CAAC,CAAC,GAAG,KAAI;AACrB,QAAA,MAAM,IAAI,GAAkB,GAAG,CAAC,IAAI,CAAC,MACnC,GAAG,CAAC,MAAM,CAAC;AACT,YAAA,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC9B,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC/D,SAAA,CAAC,CACH,CAAA;AACD,QAAA,OAAO,IAAI,CAAA;AACb,KAAC,CAAC,CACH;CACF;;;;"}
@@ -1,3 +1,4 @@
1
+ import type { ZodType, ZodTypeDef } from 'zod';
1
2
  /**
2
3
  * Copy of the ViteJS import meta interface
3
4
  */
@@ -5,15 +6,24 @@ interface MetaEnv {
5
6
  [key: string]: unknown;
6
7
  }
7
8
  export declare type Variable<T> = {
8
- names: string[];
9
+ name: string;
10
+ asEnv: (value: T) => Record<string, string>;
11
+ zod: ZodVariable<T>;
9
12
  vite: ViteVariable<T>;
10
13
  };
14
+ export declare type ZodTypeProvider<T> = (zod: typeof import('zod')) => ZodType<T | undefined, ZodTypeDef, T | undefined>;
15
+ export declare type ZodVariable<T> = {
16
+ type: ZodTypeProvider<T>;
17
+ };
18
+ export declare type Converter<T> = {
19
+ convert: (target: unknown) => T | null;
20
+ asString: (value: T) => string;
21
+ type: ZodTypeProvider<T>;
22
+ };
11
23
  export declare type ViteVariable<T> = {
12
24
  key: string;
13
25
  get: (env: MetaEnv) => T | null;
14
26
  getOrDefault: (env: MetaEnv, def: T) => T;
15
27
  };
16
- export declare function createVariable<T = string | boolean>(key: string, conversion: (target: unknown) => T | null): Variable<T>;
17
- export declare function stringConversion(): (target: unknown) => string | null;
18
- export declare function booleanConversion(): (target: unknown) => boolean | null;
28
+ export declare function createVariable<T>(key: string, converter: Converter<T>): Variable<T>;
19
29
  export {};
@@ -1,8 +1,12 @@
1
- function createVariable(key, conversion) {
1
+ function createVariable(key, converter) {
2
2
  const viteKey = `VITE_${key.toUpperCase()}`;
3
- const viteGet = (env) => conversion(env[viteKey]);
3
+ const viteGet = (env) => converter.convert(env[viteKey]);
4
4
  return {
5
- names: [key, toCamelCase(key)],
5
+ name: toCamelCase(key),
6
+ asEnv: (value) => ({ [viteKey]: converter.asString(value) }),
7
+ zod: {
8
+ type: converter.type,
9
+ },
6
10
  vite: {
7
11
  key: viteKey,
8
12
  get: viteGet,
@@ -15,33 +19,6 @@ function toCamelCase(key) {
15
19
  return $1.toUpperCase().replace('-', '').replace('_', '');
16
20
  });
17
21
  }
18
- function stringConversion() {
19
- return (target) => {
20
- if (target === null || target === undefined || target === '') {
21
- return null;
22
- }
23
- return String(target);
24
- };
25
- }
26
- function booleanConversion() {
27
- return (target) => {
28
- if (target === null)
29
- return null;
30
- if (target === undefined)
31
- return null;
32
- switch (typeof target) {
33
- case 'boolean':
34
- return target;
35
- case 'string':
36
- const lowerCase = target.toLowerCase().trim();
37
- return lowerCase === 'true' || lowerCase === 't' || lowerCase === '1';
38
- case 'number':
39
- return target !== 0;
40
- default:
41
- return null;
42
- }
43
- };
44
- }
45
22
 
46
- export { booleanConversion, createVariable, stringConversion };
23
+ export { createVariable };
47
24
  //# sourceMappingURL=variable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"variable.js","sources":["../../../src/variables/variable.ts"],"sourcesContent":[null],"names":[],"mappings":"AAkBgB,SAAA,cAAc,CAC5B,GAAW,EACX,UAAyC,EAAA;IAEzC,MAAM,OAAO,GAAG,CAAQ,KAAA,EAAA,GAAG,CAAC,WAAW,EAAE,EAAE,CAAA;AAC3C,IAAA,MAAM,OAAO,GAAG,CAAC,GAAY,KAAK,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAE1D,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;AAC9B,QAAA,IAAI,EAAE;AACJ,YAAA,GAAG,EAAE,OAAO;AACZ,YAAA,GAAG,EAAE,OAAO;AACZ,YAAA,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG;AAChD,SAAA;KACF,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAA;AAC9B,IAAA,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,EAAE,KAAI;AACvD,QAAA,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AAC3D,KAAC,CAAC,CAAA;AACJ,CAAC;SAEe,gBAAgB,GAAA;IAC9B,OAAO,CAAC,MAAe,KAAmB;QACxC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE;AAC5D,YAAA,OAAO,IAAI,CAAA;AACZ,SAAA;AAED,QAAA,OAAO,MAAM,CAAC,MAAM,CAAC,CAAA;AACvB,KAAC,CAAA;AACH,CAAC;SAEe,iBAAiB,GAAA;IAC/B,OAAO,CAAC,MAAe,KAAoB;QACzC,IAAI,MAAM,KAAK,IAAI;AAAE,YAAA,OAAO,IAAI,CAAA;QAChC,IAAI,MAAM,KAAK,SAAS;AAAE,YAAA,OAAO,IAAI,CAAA;QAErC,QAAQ,OAAO,MAAM;AACnB,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,MAAM,CAAA;AACf,YAAA,KAAK,QAAQ;gBACX,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAA;gBAC7C,OAAO,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,GAAG,CAAA;AACvE,YAAA,KAAK,QAAQ;gBACX,OAAO,MAAM,KAAK,CAAC,CAAA;AACrB,YAAA;AACE,gBAAA,OAAO,IAAI,CAAA;AACd,SAAA;AACH,KAAC,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"variable.js","sources":["../../../src/variables/variable.ts"],"sourcesContent":[null],"names":[],"mappings":"AAoCgB,SAAA,cAAc,CAC5B,GAAW,EACX,SAAuB,EAAA;IAEvB,MAAM,OAAO,GAAG,CAAQ,KAAA,EAAA,GAAG,CAAC,WAAW,EAAE,EAAE,CAAA;AAC3C,IAAA,MAAM,OAAO,GAAG,CAAC,GAAY,KAAK,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAEjE,OAAO;AACL,QAAA,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC;AACtB,QAAA,KAAK,EAAE,CAAC,KAAQ,MAAM,EAAE,CAAC,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/D,QAAA,GAAG,EAAE;YACH,IAAI,EAAE,SAAS,CAAC,IAAI;AACrB,SAAA;AACD,QAAA,IAAI,EAAE;AACJ,YAAA,GAAG,EAAE,OAAO;AACZ,YAAA,GAAG,EAAE,OAAO;AACZ,YAAA,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG;AAChD,SAAA;KACF,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAA;AAC9B,IAAA,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,EAAE,KAAI;AACvD,QAAA,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AAC3D,KAAC,CAAC,CAAA;AACJ;;;;"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@magidoc/plugin-starter-variables",
3
3
  "description": "A shared library that contains common Magidoc starter environment variables keys.",
4
4
  "private": false,
5
- "version": "0.9.3",
5
+ "version": "0.11.0",
6
6
  "type": "module",
7
7
  "license": "MIT",
8
8
  "main": "./build/index.js",
@@ -20,6 +20,9 @@
20
20
  "tslib": "^2.4.0",
21
21
  "typescript": "^4.6.3"
22
22
  },
23
+ "optionalDependencies": {
24
+ "zod": "^3.14.4"
25
+ },
23
26
  "scripts": {
24
27
  "start": "pnpm build:rollup && node build/index.js",
25
28
  "build": "run-p build:*",
package/rollup.config.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  const { defineConfig } = require('rollup')
2
2
  const typescript = require('@rollup/plugin-typescript')
3
- const shebang = require('rollup-plugin-preserve-shebang')
4
3
 
5
4
  module.exports = defineConfig({
6
5
  input: ['src/index.ts'],
7
6
  plugins: [typescript()],
7
+ external: ['zod'],
8
8
  output: {
9
9
  dir: 'build',
10
10
  format: 'esm',
package/src/index.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import templates from './variables/templates'
2
2
  import magidoc from './variables/magidoc'
3
3
  import type { Variable, ViteVariable } from './variables/variable'
4
+ import type { Page } from './variables/templates'
4
5
 
5
6
  export { templates }
6
7
  export { magidoc }
7
- export type { Variable, ViteVariable }
8
+ export type { Variable, ViteVariable, Page }
@@ -0,0 +1,25 @@
1
+ import type { Converter, ZodTypeProvider } from '../variable'
2
+
3
+ export function arrayConverter<V>(
4
+ valueType: ZodTypeProvider<V>,
5
+ ): Converter<Array<V | undefined>> {
6
+ return {
7
+ convert: (target) => {
8
+ if (Array.isArray(target)) {
9
+ return target as Array<V>
10
+ }
11
+
12
+ if (typeof target === 'string') {
13
+ const result = JSON.parse(target) as Record<string, V>
14
+ if (!Array.isArray(result)) {
15
+ return null
16
+ }
17
+ return result
18
+ }
19
+
20
+ return null
21
+ },
22
+ asString: (value) => JSON.stringify(value),
23
+ type: (z) => z.array(valueType(z)).optional(),
24
+ }
25
+ }
@@ -0,0 +1,24 @@
1
+ import type { Converter } from '../variable'
2
+
3
+ export function booleanConverter(): Converter<boolean> {
4
+ return {
5
+ convert: (target: unknown): boolean | null => {
6
+ if (target === null) return null
7
+ if (target === undefined) return null
8
+
9
+ switch (typeof target) {
10
+ case 'boolean':
11
+ return target
12
+ case 'string':
13
+ const lowerCase = target.toLowerCase().trim()
14
+ return lowerCase === 'true' || lowerCase === 't' || lowerCase === '1'
15
+ case 'number':
16
+ return target !== 0
17
+ default:
18
+ return null
19
+ }
20
+ },
21
+ asString: (value) => String(value),
22
+ type: (z) => z.boolean().optional(),
23
+ }
24
+ }
@@ -0,0 +1,6 @@
1
+ import { stringConverter } from './string'
2
+ import { booleanConverter } from './boolean'
3
+ import { recordConverter } from './record'
4
+ import { arrayConverter } from './array'
5
+
6
+ export { stringConverter, booleanConverter, recordConverter, arrayConverter }
@@ -0,0 +1,25 @@
1
+ import type { Converter, ZodTypeProvider } from '../variable'
2
+
3
+ export function recordConverter<V>(
4
+ valueType: ZodTypeProvider<V>,
5
+ ): Converter<Record<string, V | undefined>> {
6
+ return {
7
+ convert: (target) => {
8
+ if (typeof target === 'object') {
9
+ return target as Record<string, V>
10
+ }
11
+
12
+ if (typeof target === 'string') {
13
+ const result = JSON.parse(target) as Record<string, V>
14
+ if (typeof result !== 'object') {
15
+ return null
16
+ }
17
+ return result
18
+ }
19
+
20
+ return null
21
+ },
22
+ asString: (value) => JSON.stringify(value),
23
+ type: (z) => z.record(valueType(z).optional()).optional(),
24
+ }
25
+ }
@@ -0,0 +1,15 @@
1
+ import type { Converter } from '../variable'
2
+
3
+ export function stringConverter(): Converter<string> {
4
+ return {
5
+ convert: (target: unknown): string | null => {
6
+ if (target === null || target === undefined || target === '') {
7
+ return null
8
+ }
9
+
10
+ return String(target)
11
+ },
12
+ asString: (value) => String(value),
13
+ type: (z) => z.string().optional(),
14
+ }
15
+ }
@@ -1,8 +1,9 @@
1
- import { booleanConversion, createVariable } from './variable'
1
+ import { booleanConverter } from './converters'
2
+ import { createVariable } from './variable'
2
3
 
3
4
  export default {
4
5
  MAGIDOC_GENERATE: createVariable<boolean>(
5
6
  'MAGIDOC_GENERATE',
6
- booleanConversion(),
7
+ booleanConverter(),
7
8
  ),
8
9
  }
@@ -1,6 +1,42 @@
1
- import { createVariable, stringConversion } from './variable'
1
+ import type { ZodType } from 'zod'
2
+ import { arrayConverter, recordConverter, stringConverter } from './converters'
3
+ import { createVariable } from './variable'
4
+
5
+ export type Page = {
6
+ title: string
7
+ content: string | Page[]
8
+ }
2
9
 
3
10
  export default {
4
- APP_LOGO: createVariable<string>('APP_LOGO', stringConversion()),
5
- APP_TITLE: createVariable<string>('APP_TITLE', stringConversion()),
11
+ APP_LOGO: createVariable<string>('APP_LOGO', stringConverter()),
12
+ APP_TITLE: createVariable<string>('APP_TITLE', stringConverter()),
13
+ QUERY_GENERATION_FACTORIES: createVariable<
14
+ Record<
15
+ string,
16
+ string | boolean | number | Record<string, unknown> | null | undefined
17
+ >
18
+ >(
19
+ 'QUERY_GENERATION_FACTORIES',
20
+ recordConverter((zod) =>
21
+ zod.union([
22
+ zod.string(),
23
+ zod.boolean(),
24
+ zod.number(),
25
+ zod.null(),
26
+ zod.record(zod.unknown()),
27
+ ]),
28
+ ),
29
+ ),
30
+ PAGES: createVariable<Array<Page | undefined>>(
31
+ 'PAGES',
32
+ arrayConverter((zod) => {
33
+ const type: ZodType<Page> = zod.lazy(() =>
34
+ zod.object({
35
+ title: zod.string().nonempty(),
36
+ content: zod.union([zod.array(type), zod.string().nonempty()]),
37
+ }),
38
+ )
39
+ return type
40
+ }),
41
+ ),
6
42
  }
@@ -1,3 +1,5 @@
1
+ import type { ZodType, ZodTypeDef } from 'zod'
2
+
1
3
  /**
2
4
  * Copy of the ViteJS import meta interface
3
5
  */
@@ -6,25 +8,45 @@ interface MetaEnv {
6
8
  }
7
9
 
8
10
  export type Variable<T> = {
9
- names: string[]
11
+ name: string
12
+ asEnv: (value: T) => Record<string, string>
13
+ zod: ZodVariable<T>
10
14
  vite: ViteVariable<T>
11
15
  }
12
16
 
17
+ export type ZodTypeProvider<T> = (
18
+ zod: typeof import('zod'),
19
+ ) => ZodType<T | undefined, ZodTypeDef, T | undefined>
20
+
21
+ export type ZodVariable<T> = {
22
+ type: ZodTypeProvider<T>
23
+ }
24
+
25
+ export type Converter<T> = {
26
+ convert: (target: unknown) => T | null
27
+ asString: (value: T) => string
28
+ type: ZodTypeProvider<T>
29
+ }
30
+
13
31
  export type ViteVariable<T> = {
14
32
  key: string
15
33
  get: (env: MetaEnv) => T | null
16
34
  getOrDefault: (env: MetaEnv, def: T) => T
17
35
  }
18
36
 
19
- export function createVariable<T = string | boolean>(
37
+ export function createVariable<T>(
20
38
  key: string,
21
- conversion: (target: unknown) => T | null,
39
+ converter: Converter<T>,
22
40
  ): Variable<T> {
23
41
  const viteKey = `VITE_${key.toUpperCase()}`
24
- const viteGet = (env: MetaEnv) => conversion(env[viteKey])
42
+ const viteGet = (env: MetaEnv) => converter.convert(env[viteKey])
25
43
 
26
44
  return {
27
- names: [key, toCamelCase(key)],
45
+ name: toCamelCase(key),
46
+ asEnv: (value: T) => ({ [viteKey]: converter.asString(value) }),
47
+ zod: {
48
+ type: converter.type,
49
+ },
28
50
  vite: {
29
51
  key: viteKey,
30
52
  get: viteGet,
@@ -38,32 +60,3 @@ function toCamelCase(key: string): string {
38
60
  return $1.toUpperCase().replace('-', '').replace('_', '')
39
61
  })
40
62
  }
41
-
42
- export function stringConversion() {
43
- return (target: unknown): string | null => {
44
- if (target === null || target === undefined || target === '') {
45
- return null
46
- }
47
-
48
- return String(target)
49
- }
50
- }
51
-
52
- export function booleanConversion() {
53
- return (target: unknown): boolean | null => {
54
- if (target === null) return null
55
- if (target === undefined) return null
56
-
57
- switch (typeof target) {
58
- case 'boolean':
59
- return target
60
- case 'string':
61
- const lowerCase = target.toLowerCase().trim()
62
- return lowerCase === 'true' || lowerCase === 't' || lowerCase === '1'
63
- case 'number':
64
- return target !== 0
65
- default:
66
- return null
67
- }
68
- }
69
- }
@@ -1,29 +1,96 @@
1
+ import type { ZodType } from 'zod'
1
2
  import * as variables from '../src/index'
2
3
  import type { Variable } from '../src/variables/variable'
4
+ import z from 'zod'
5
+ import type { Page } from '../src/index'
3
6
 
4
7
  describe('variables', () => {
5
8
  it('contains the right number of export keys', () => {
6
9
  expect(Object.keys(variables)).toEqual(['templates', 'magidoc'])
7
10
  })
8
11
 
9
- it('contains the right templates variables', () => {
10
- expect(Object.keys(variables.templates)).toEqual(['APP_LOGO', 'APP_TITLE'])
12
+ describe('template variables', () => {
13
+ it('contains the right templates variables', () => {
14
+ expect(Object.keys(variables.templates)).toEqual([
15
+ 'APP_LOGO',
16
+ 'APP_TITLE',
17
+ 'QUERY_GENERATION_FACTORIES',
18
+ 'PAGES',
19
+ ])
20
+ })
11
21
 
12
- testStringVariable(variables.templates.APP_TITLE, 'VITE_APP_TITLE')
13
- testStringVariable(variables.templates.APP_LOGO, 'VITE_APP_LOGO')
22
+ test('app title', () => {
23
+ testStringVariable(
24
+ variables.templates.APP_TITLE,
25
+ 'VITE_APP_TITLE',
26
+ z.string().optional(),
27
+ )
28
+ })
29
+
30
+ test('app logo', () => {
31
+ testStringVariable(
32
+ variables.templates.APP_LOGO,
33
+ 'VITE_APP_LOGO',
34
+ z.string().optional(),
35
+ )
36
+ })
37
+
38
+ test('query generation factories', () => {
39
+ testRecordVariable(
40
+ variables.templates.QUERY_GENERATION_FACTORIES,
41
+ 'VITE_QUERY_GENERATION_FACTORIES',
42
+ z
43
+ .record(
44
+ z
45
+ .union([
46
+ z.string(),
47
+ z.boolean(),
48
+ z.number(),
49
+ z.null(),
50
+ z.record(z.unknown()),
51
+ ])
52
+ .optional(),
53
+ )
54
+ .optional(),
55
+ )
56
+ })
57
+
58
+ test('pages', () => {
59
+ const pagesType: ZodType<Page> = z.lazy(() =>
60
+ z.object({
61
+ title: z.string(),
62
+ content: z.union([z.array(pagesType), z.string()]),
63
+ }),
64
+ )
65
+
66
+ testArrayVariable(
67
+ variables.templates.PAGES,
68
+ 'VITE_PAGES',
69
+ z.array(pagesType).optional(),
70
+ )
71
+ })
14
72
  })
15
73
 
16
- it('contains the right magidoc variables', () => {
17
- expect(Object.keys(variables.magidoc)).toEqual(['MAGIDOC_GENERATE'])
74
+ describe('magidoc variables', () => {
75
+ it('contains the right magidoc variables', () => {
76
+ expect(Object.keys(variables.magidoc)).toEqual(['MAGIDOC_GENERATE'])
77
+ })
18
78
 
19
- testBooleanVariable(
20
- variables.magidoc.MAGIDOC_GENERATE,
21
- 'VITE_MAGIDOC_GENERATE',
22
- )
79
+ test('magidoc generate', () => {
80
+ testBooleanVariable(
81
+ variables.magidoc.MAGIDOC_GENERATE,
82
+ 'VITE_MAGIDOC_GENERATE',
83
+ z.boolean().optional(),
84
+ )
85
+ })
23
86
  })
24
87
  })
25
88
 
26
- function testStringVariable(target: Variable<string>, viteKey: string) {
89
+ function testStringVariable(
90
+ target: Variable<string>,
91
+ viteKey: string,
92
+ expectedZod: ZodType<any>,
93
+ ) {
27
94
  expect(target.vite.key).toEqual(viteKey)
28
95
 
29
96
  expect(target.vite.get({ [viteKey]: 'Potato' })).toBe('Potato')
@@ -37,9 +104,17 @@ function testStringVariable(target: Variable<string>, viteKey: string) {
37
104
  'false',
38
105
  )
39
106
  expect(target.vite.getOrDefault({}, 'Default')).toBe('Default')
107
+
108
+ expect(target.asEnv('Potato')).toEqual({ [viteKey]: 'Potato' })
109
+
110
+ ensureZodTypeEqual(target, expectedZod)
40
111
  }
41
112
 
42
- function testBooleanVariable(target: Variable<boolean>, viteKey: string) {
113
+ function testBooleanVariable(
114
+ target: Variable<boolean>,
115
+ viteKey: string,
116
+ expectedZod: ZodType<any>,
117
+ ) {
43
118
  expect(target.vite.key).toEqual(viteKey)
44
119
 
45
120
  expect(target.vite.get({ [viteKey]: true })).toBe(true)
@@ -61,4 +136,88 @@ function testBooleanVariable(target: Variable<boolean>, viteKey: string) {
61
136
  expect(target.vite.getOrDefault({ [viteKey]: false }, true)).toBe(false)
62
137
  expect(target.vite.getOrDefault({ [viteKey]: {} }, true)).toBe(true)
63
138
  expect(target.vite.getOrDefault({}, true)).toBe(true)
139
+
140
+ expect(target.asEnv(true)).toEqual({ [viteKey]: 'true' })
141
+ expect(target.asEnv(false)).toEqual({ [viteKey]: 'false' })
142
+
143
+ ensureZodTypeEqual(target, expectedZod)
144
+ }
145
+
146
+ function testRecordVariable(
147
+ target: Variable<Record<string, any>>,
148
+ viteKey: string,
149
+ expectedZod: ZodType<any>,
150
+ ) {
151
+ expect(target.vite.key).toEqual(viteKey)
152
+
153
+ expect(target.vite.get({ [viteKey]: true })).toBeNull()
154
+ expect(target.vite.get({ [viteKey]: 'true' })).toBeNull()
155
+ expect(target.vite.get({ [viteKey]: '4234' })).toBeNull()
156
+ expect(target.vite.get({ [viteKey]: 4234 })).toBeNull()
157
+
158
+ expect(target.vite.get({ [viteKey]: { abc: '123' } })).toEqual({ abc: '123' })
159
+ expect(
160
+ target.vite.get({ [viteKey]: JSON.stringify({ abc: '123' }) }),
161
+ ).toEqual({ abc: '123' })
162
+
163
+ expect(target.vite.getOrDefault({ [viteKey]: false }, { abc: 123 })).toEqual({
164
+ abc: 123,
165
+ })
166
+ expect(target.vite.getOrDefault({ [viteKey]: {} }, { abc: 123 })).toEqual({})
167
+ expect(target.vite.getOrDefault({}, { abc: 123 })).toEqual({ abc: 123 })
168
+
169
+ expect(target.asEnv({ abc: 123 })).toEqual({
170
+ [viteKey]: JSON.stringify({ abc: 123 }),
171
+ })
172
+ expect(target.asEnv({})).toEqual({ [viteKey]: '{}' })
173
+
174
+ ensureZodTypeEqual(target, expectedZod)
175
+ }
176
+
177
+ function testArrayVariable(
178
+ target: Variable<Array<any>>,
179
+ viteKey: string,
180
+ expectedZod: ZodType<any>,
181
+ ) {
182
+ expect(target.vite.key).toEqual(viteKey)
183
+
184
+ expect(target.vite.get({ [viteKey]: true })).toBeNull()
185
+ expect(target.vite.get({ [viteKey]: 'true' })).toBeNull()
186
+ expect(target.vite.get({ [viteKey]: '4234' })).toBeNull()
187
+ expect(target.vite.get({ [viteKey]: 4234 })).toBeNull()
188
+ expect(target.vite.get({ [viteKey]: {} })).toBeNull()
189
+
190
+ expect(target.vite.get({ [viteKey]: [{ abc: '123' }] })).toEqual([
191
+ { abc: '123' },
192
+ ])
193
+ expect(
194
+ target.vite.get({ [viteKey]: JSON.stringify([{ abc: '123' }]) }),
195
+ ).toEqual([{ abc: '123' }])
196
+
197
+ expect(
198
+ target.vite.getOrDefault({ [viteKey]: false }, [{ abc: 123 }]),
199
+ ).toEqual([
200
+ {
201
+ abc: 123,
202
+ },
203
+ ])
204
+ expect(target.vite.getOrDefault({ [viteKey]: [] }, [{ abc: 123 }])).toEqual(
205
+ [],
206
+ )
207
+ expect(target.vite.getOrDefault({}, [{ abc: 123 }])).toEqual([{ abc: 123 }])
208
+
209
+ expect(target.asEnv([{ abc: 123 }])).toEqual({
210
+ [viteKey]: JSON.stringify([{ abc: 123 }]),
211
+ })
212
+ expect(target.asEnv([])).toEqual({ [viteKey]: '[]' })
213
+
214
+ ensureZodTypeEqual(target, expectedZod)
215
+ }
216
+
217
+ function ensureZodTypeEqual(target: Variable<any>, expected: ZodType<any>) {
218
+ // @ts-ignore
219
+ // this does a good enough compare to make sure they have the same schema
220
+ expect(JSON.parse(JSON.stringify(target.zod.type(z)))).toEqual(
221
+ JSON.parse(JSON.stringify(expected, null, 2)),
222
+ )
64
223
  }