@ifunny/ifunny-api-types 1.0.3 → 1.2.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 (215) hide show
  1. package/.devenv/bootstrap/bootstrapLib.nix +630 -0
  2. package/.devenv/bootstrap/default.nix +22 -0
  3. package/.devenv/bootstrap/resolve-lock.nix +190 -0
  4. package/.devenv/changelog-cache.json +9 -0
  5. package/.devenv/devenv.fish +252 -0
  6. package/.devenv/imports.txt +0 -0
  7. package/.devenv/input-paths.txt +10 -0
  8. package/.devenv/load-exports +1 -0
  9. package/.devenv/nix-eval-cache.db +0 -0
  10. package/.devenv/nix-eval-cache.db-shm +0 -0
  11. package/.devenv/nix-eval-cache.db-wal +0 -0
  12. package/.devenv/nix-eval-cache.db.init.lock +0 -0
  13. package/.devenv/nixpkgs-config-99f33fda17d41bc9.nix +17 -0
  14. package/.devenv/nixpkgs-config-c46eff8321b73149.nix +29 -0
  15. package/.devenv/profiles/nix/bootstrap/bootstrapLib.nix +571 -0
  16. package/.devenv/profiles/nix/bootstrap/default.nix +19 -0
  17. package/.devenv/profiles/nix/bootstrap/resolve-lock.nix +157 -0
  18. package/.devenv/profiles/nix/imports.txt +0 -0
  19. package/.devenv/profiles/nix/input-paths.txt +4 -0
  20. package/.devenv/profiles/nix/load-exports +1 -0
  21. package/.devenv/profiles/nix/nix-eval-cache.db +0 -0
  22. package/.devenv/profiles/nix/nix-eval-cache.db-shm +0 -0
  23. package/.devenv/profiles/nix/nix-eval-cache.db-wal +0 -0
  24. package/.devenv/profiles/nix/nixpkgs-config-99f33fda17d41bc9.nix +17 -0
  25. package/.devenv/profiles/nix/shell-0d722b4fe4724c8e.sh +2270 -0
  26. package/.devenv/profiles/nix/shell-314b72302fb2c916.sh +2270 -0
  27. package/.devenv/profiles/nix/shell-6a4b00b5ca837a3b.sh +2270 -0
  28. package/.devenv/profiles/nix/shell-956adc1e664f64c3.sh +2270 -0
  29. package/.devenv/profiles/nix/shell-9dbff87fad44e8d9.sh +2270 -0
  30. package/.devenv/profiles/nix/shell-b1e9e1f82076662f.sh +2270 -0
  31. package/.devenv/profiles/nix/shell-b4f4bbfa36797bee.sh +2270 -0
  32. package/.devenv/profiles/nix/shell-c4b190d331c48d67.sh +2270 -0
  33. package/.devenv/profiles/nix/state/files.json +1 -0
  34. package/.devenv/profiles/nix/state/tasks.db +0 -0
  35. package/.devenv/profiles/nix/state/tasks.db-shm +0 -0
  36. package/.devenv/profiles/nix/state/tasks.db-wal +0 -0
  37. package/.devenv/profiles/nix/task-names.txt +5 -0
  38. package/.devenv/shell-086ca2c39799e6a6.sh +2270 -0
  39. package/.devenv/shell-2c06a35dd99be3d1.sh +2270 -0
  40. package/.devenv/shell-36f1fe0faec08873.sh +2270 -0
  41. package/.devenv/shell-676361065bda5b43.sh +2270 -0
  42. package/.devenv/shell-9f6cb513d1721fef.sh +2270 -0
  43. package/.devenv/shell-c0e4459b4f5922d7.sh +2270 -0
  44. package/.devenv/shell-c862a0db6e9ad5f4.sh +2270 -0
  45. package/.devenv/shell-d71ade933a43e837.sh +2270 -0
  46. package/.devenv/shell-dd73aac05b182946.sh +2270 -0
  47. package/.devenv/shell-e39d0b30a7e0eb13.sh +2270 -0
  48. package/.devenv/shell-env.sh +2263 -0
  49. package/.devenv/shell-f924d749ff8c17ee.sh +2270 -0
  50. package/.devenv/shell-rcfile.sh +152 -0
  51. package/.devenv/state/files.json +1 -0
  52. package/.devenv/state/tasks.db +0 -0
  53. package/.devenv/state/tasks.db-shm +0 -0
  54. package/.devenv/state/tasks.db-wal +0 -0
  55. package/.devenv/state/tasks.db.init.lock +0 -0
  56. package/.devenv/task-names.txt +5 -0
  57. package/.github/workflows/codeql.yml +72 -72
  58. package/.github/workflows/test.yml +31 -31
  59. package/CHANGELOG.md +8405 -417
  60. package/LICENSE +121 -121
  61. package/README.md +2 -2
  62. package/devenv.lock +65 -0
  63. package/devenv.nix +38 -0
  64. package/devenv.yaml +18 -0
  65. package/eslint.config.mjs +18 -0
  66. package/package.json +59 -50
  67. package/prettier.config.js +15 -0
  68. package/dist/errors/bad_request.js +0 -8
  69. package/dist/errors/bad_request.js.map +0 -1
  70. package/dist/errors/captcha_required.js +0 -19
  71. package/dist/errors/captcha_required.js.map +0 -1
  72. package/dist/errors/email_exists.js +0 -8
  73. package/dist/errors/email_exists.js.map +0 -1
  74. package/dist/errors/error.js +0 -3
  75. package/dist/errors/error.js.map +0 -1
  76. package/dist/errors/error_base.js +0 -43
  77. package/dist/errors/error_base.js.map +0 -1
  78. package/dist/errors/index.js +0 -29
  79. package/dist/errors/index.js.map +0 -1
  80. package/dist/errors/invalid_client.js +0 -8
  81. package/dist/errors/invalid_client.js.map +0 -1
  82. package/dist/errors/invalid_email.js +0 -8
  83. package/dist/errors/invalid_email.js.map +0 -1
  84. package/dist/errors/invalid_grant.js +0 -8
  85. package/dist/errors/invalid_grant.js.map +0 -1
  86. package/dist/errors/not_found.js +0 -3
  87. package/dist/errors/not_found.js.map +0 -1
  88. package/dist/errors/permission_denied.js +0 -8
  89. package/dist/errors/permission_denied.js.map +0 -1
  90. package/dist/errors/unauthorized.js +0 -8
  91. package/dist/errors/unauthorized.js.map +0 -1
  92. package/dist/errors/wrong_params.js +0 -8
  93. package/dist/errors/wrong_params.js.map +0 -1
  94. package/dist/index.js +0 -21
  95. package/dist/index.js.map +0 -1
  96. package/dist/payloads/activity.js +0 -50
  97. package/dist/payloads/activity.js.map +0 -1
  98. package/dist/payloads/app.js +0 -3
  99. package/dist/payloads/app.js.map +0 -1
  100. package/dist/payloads/appeal.js +0 -14
  101. package/dist/payloads/appeal.js.map +0 -1
  102. package/dist/payloads/ban.js +0 -36
  103. package/dist/payloads/ban.js.map +0 -1
  104. package/dist/payloads/base.js +0 -3
  105. package/dist/payloads/base.js.map +0 -1
  106. package/dist/payloads/client.js +0 -13
  107. package/dist/payloads/client.js.map +0 -1
  108. package/dist/payloads/comment.js +0 -42
  109. package/dist/payloads/comment.js.map +0 -1
  110. package/dist/payloads/content.js +0 -176
  111. package/dist/payloads/content.js.map +0 -1
  112. package/dist/payloads/index.js +0 -27
  113. package/dist/payloads/index.js.map +0 -1
  114. package/dist/payloads/strike.js +0 -3
  115. package/dist/payloads/strike.js.map +0 -1
  116. package/dist/payloads/user.js +0 -214
  117. package/dist/payloads/user.js.map +0 -1
  118. package/dist/rest/account.js +0 -3
  119. package/dist/rest/account.js.map +0 -1
  120. package/dist/rest/content.js +0 -54
  121. package/dist/rest/content.js.map +0 -1
  122. package/dist/rest/counters.js +0 -3
  123. package/dist/rest/counters.js.map +0 -1
  124. package/dist/rest/endpoints.js +0 -199
  125. package/dist/rest/endpoints.js.map +0 -1
  126. package/dist/rest/explore.js +0 -82
  127. package/dist/rest/explore.js.map +0 -1
  128. package/dist/rest/feeds.js +0 -3
  129. package/dist/rest/feeds.js.map +0 -1
  130. package/dist/rest/index.js +0 -25
  131. package/dist/rest/index.js.map +0 -1
  132. package/dist/rest/issues.js +0 -3
  133. package/dist/rest/issues.js.map +0 -1
  134. package/dist/rest/oauth2.js +0 -9
  135. package/dist/rest/oauth2.js.map +0 -1
  136. package/dist/utils/index.js +0 -19
  137. package/dist/utils/index.js.map +0 -1
  138. package/dist/utils/rest.js +0 -3
  139. package/dist/utils/rest.js.map +0 -1
  140. package/dist/utils/util.js +0 -3
  141. package/dist/utils/util.js.map +0 -1
  142. package/types/errors/bad_request.d.ts +0 -12
  143. package/types/errors/bad_request.d.ts.map +0 -1
  144. package/types/errors/captcha_required.d.ts +0 -33
  145. package/types/errors/captcha_required.d.ts.map +0 -1
  146. package/types/errors/email_exists.d.ts +0 -15
  147. package/types/errors/email_exists.d.ts.map +0 -1
  148. package/types/errors/error.d.ts +0 -29
  149. package/types/errors/error.d.ts.map +0 -1
  150. package/types/errors/error_base.d.ts +0 -61
  151. package/types/errors/error_base.d.ts.map +0 -1
  152. package/types/errors/index.d.ts +0 -13
  153. package/types/errors/index.d.ts.map +0 -1
  154. package/types/errors/invalid_client.d.ts +0 -15
  155. package/types/errors/invalid_client.d.ts.map +0 -1
  156. package/types/errors/invalid_email.d.ts +0 -15
  157. package/types/errors/invalid_email.d.ts.map +0 -1
  158. package/types/errors/invalid_grant.d.ts +0 -12
  159. package/types/errors/invalid_grant.d.ts.map +0 -1
  160. package/types/errors/not_found.d.ts +0 -8
  161. package/types/errors/not_found.d.ts.map +0 -1
  162. package/types/errors/permission_denied.d.ts +0 -12
  163. package/types/errors/permission_denied.d.ts.map +0 -1
  164. package/types/errors/unauthorized.d.ts +0 -12
  165. package/types/errors/unauthorized.d.ts.map +0 -1
  166. package/types/errors/wrong_params.d.ts +0 -11
  167. package/types/errors/wrong_params.d.ts.map +0 -1
  168. package/types/index.d.ts +0 -5
  169. package/types/index.d.ts.map +0 -1
  170. package/types/payloads/activity.d.ts +0 -114
  171. package/types/payloads/activity.d.ts.map +0 -1
  172. package/types/payloads/app.d.ts +0 -266
  173. package/types/payloads/app.d.ts.map +0 -1
  174. package/types/payloads/appeal.d.ts +0 -22
  175. package/types/payloads/appeal.d.ts.map +0 -1
  176. package/types/payloads/ban.d.ts +0 -85
  177. package/types/payloads/ban.d.ts.map +0 -1
  178. package/types/payloads/base.d.ts +0 -5
  179. package/types/payloads/base.d.ts.map +0 -1
  180. package/types/payloads/client.d.ts +0 -106
  181. package/types/payloads/client.d.ts.map +0 -1
  182. package/types/payloads/comment.d.ts +0 -124
  183. package/types/payloads/comment.d.ts.map +0 -1
  184. package/types/payloads/content.d.ts +0 -676
  185. package/types/payloads/content.d.ts.map +0 -1
  186. package/types/payloads/index.d.ts +0 -11
  187. package/types/payloads/index.d.ts.map +0 -1
  188. package/types/payloads/strike.d.ts +0 -15
  189. package/types/payloads/strike.d.ts.map +0 -1
  190. package/types/payloads/user.d.ts +0 -515
  191. package/types/payloads/user.d.ts.map +0 -1
  192. package/types/rest/account.d.ts +0 -4
  193. package/types/rest/account.d.ts.map +0 -1
  194. package/types/rest/content.d.ts +0 -96
  195. package/types/rest/content.d.ts.map +0 -1
  196. package/types/rest/counters.d.ts +0 -10
  197. package/types/rest/counters.d.ts.map +0 -1
  198. package/types/rest/endpoints.d.ts +0 -153
  199. package/types/rest/endpoints.d.ts.map +0 -1
  200. package/types/rest/explore.d.ts +0 -113
  201. package/types/rest/explore.d.ts.map +0 -1
  202. package/types/rest/feeds.d.ts +0 -17
  203. package/types/rest/feeds.d.ts.map +0 -1
  204. package/types/rest/index.d.ts +0 -9
  205. package/types/rest/index.d.ts.map +0 -1
  206. package/types/rest/issues.d.ts +0 -16
  207. package/types/rest/issues.d.ts.map +0 -1
  208. package/types/rest/oauth2.d.ts +0 -37
  209. package/types/rest/oauth2.d.ts.map +0 -1
  210. package/types/utils/index.d.ts +0 -3
  211. package/types/utils/index.d.ts.map +0 -1
  212. package/types/utils/rest.d.ts +0 -50
  213. package/types/utils/rest.d.ts.map +0 -1
  214. package/types/utils/util.d.ts +0 -80
  215. package/types/utils/util.d.ts.map +0 -1
@@ -0,0 +1,630 @@
1
+ # Shared library functions for devenv evaluation
2
+ { inputs }:
3
+
4
+ rec {
5
+ # Helper to get overlays for a given input
6
+ getOverlays =
7
+ inputName: inputAttrs:
8
+ let
9
+ lib = inputs.nixpkgs.lib;
10
+ in
11
+ map (
12
+ overlay:
13
+ let
14
+ input =
15
+ inputs.${inputName} or (throw "No such input `${inputName}` while trying to configure overlays.");
16
+ in
17
+ input.overlays.${overlay}
18
+ or (throw "Input `${inputName}` has no overlay called `${overlay}`. Supported overlays: ${lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")
19
+ ) inputAttrs.overlays or [ ];
20
+
21
+ # Main function to create devenv configuration for a specific system with profiles support
22
+ # This is the full-featured version used by default.nix
23
+ mkDevenvForSystem =
24
+ {
25
+ version,
26
+ is_development_version ? false,
27
+ require_version_match ? false,
28
+ system,
29
+ devenv_root,
30
+ devenv_lock,
31
+ git_root ? null,
32
+ devenv_dotfile,
33
+ devenv_dotfile_path,
34
+ devenv_tmpdir,
35
+ devenv_runtime,
36
+ devenv_state ? null,
37
+ devenv_istesting ? false,
38
+ devenv_direnvrc_latest_version,
39
+ active_profiles ? [ ],
40
+ hostname,
41
+ username,
42
+ cli_options ? [ ],
43
+ skip_local_src ? false,
44
+ secretspec ? null,
45
+ devenv_inputs ? { },
46
+ devenv_imports ? [ ],
47
+ impure ? false,
48
+ nixpkgs_config ? { },
49
+ lock_fingerprint ? null,
50
+ primops ? { },
51
+ }:
52
+ let
53
+ inherit (inputs) nixpkgs;
54
+ lib = nixpkgs.lib;
55
+ targetSystem = system;
56
+
57
+ overlays = lib.flatten (lib.mapAttrsToList getOverlays devenv_inputs);
58
+ unfreePackageError =
59
+ pkg:
60
+ let
61
+ name = lib.getName pkg;
62
+ in
63
+ throw ''
64
+ devenv: package '${name}' has an unfree license.
65
+
66
+ To allow all unfree packages, add this to devenv.yaml:
67
+
68
+ allow_unfree: true
69
+
70
+ To allow only this package, add this to devenv.yaml:
71
+
72
+ nixpkgs:
73
+ permitted_unfree_packages:
74
+ - ${name}
75
+ '';
76
+
77
+ # Helper to create pkgs for a given system with nixpkgs_config
78
+ mkPkgsForSystem =
79
+ evalSystem:
80
+ import nixpkgs {
81
+ system = evalSystem;
82
+ config =
83
+ nixpkgs_config
84
+ // {
85
+ # nixpkgs' check-meta.nix natively handles permittedInsecurePackages
86
+ # via allowInsecureDefaultPredicate using the full derivation name.
87
+ # We must NOT override allowInsecurePredicate here, as lib.getName
88
+ # strips the version, causing mismatches with user-provided entries
89
+ # like "openssl-1.1.1w".
90
+ #
91
+ # For unfree packages, nixpkgs does not natively support
92
+ # permittedUnfreePackages, so we provide a custom predicate.
93
+ allowUnfreePredicate =
94
+ if nixpkgs_config.allowUnfree or false then
95
+ (_: true)
96
+ else if (nixpkgs_config.permittedUnfreePackages or [ ]) != [ ] then
97
+ (
98
+ pkg:
99
+ builtins.elem (lib.getName pkg) (nixpkgs_config.permittedUnfreePackages or [ ])
100
+ || unfreePackageError pkg
101
+ )
102
+ else
103
+ unfreePackageError;
104
+ }
105
+ // lib.optionalAttrs ((nixpkgs_config.allowlistedLicenses or [ ]) != [ ]) {
106
+ allowlistedLicenses = map (name: lib.licenses.${name}) (nixpkgs_config.allowlistedLicenses or [ ]);
107
+ }
108
+ // lib.optionalAttrs ((nixpkgs_config.blocklistedLicenses or [ ]) != [ ]) {
109
+ blocklistedLicenses = map (name: lib.licenses.${name}) (nixpkgs_config.blocklistedLicenses or [ ]);
110
+ };
111
+ inherit overlays;
112
+ };
113
+
114
+ pkgsBootstrap = mkPkgsForSystem targetSystem;
115
+
116
+ # Helper to resolve a path to a list of module files, trying .nix first then /devenv.nix.
117
+ # Includes devenv.local.nix when present.
118
+ # Keep the entries as unimported paths: the module system uses them as each module's
119
+ # file (for error locations) and key (for deduplication).
120
+ tryImport =
121
+ resolvedPath: basePath:
122
+ if lib.hasSuffix ".nix" basePath then
123
+ [ resolvedPath ]
124
+ else
125
+ let
126
+ devenvpath = resolvedPath + "/devenv.nix";
127
+ localpath = resolvedPath + "/devenv.local.nix";
128
+ in
129
+ if builtins.pathExists devenvpath then
130
+ [ devenvpath ] ++ lib.optional (builtins.pathExists localpath) localpath
131
+ else
132
+ throw (basePath + "/devenv.nix file does not exist");
133
+
134
+ importModule =
135
+ path:
136
+ if lib.hasPrefix "path:" path then
137
+ # path: prefix indicates a local filesystem path - strip it and import directly
138
+ let
139
+ actualPath = builtins.substring 5 999999 path;
140
+ in
141
+ tryImport (/. + actualPath) path
142
+ else if lib.hasPrefix "/" path then
143
+ # Absolute path - import directly (avoids input resolution and NAR hash computation)
144
+ tryImport (/. + path) path
145
+ else if lib.hasPrefix "./" path then
146
+ # Relative paths are relative to devenv_root, not bootstrap directory
147
+ let
148
+ relPath = builtins.substring 1 255 path;
149
+ in
150
+ tryImport (/. + devenv_root + relPath) path
151
+ else if lib.hasPrefix "../" path then
152
+ # Parent relative paths also relative to devenv_root
153
+ tryImport (/. + devenv_root + "/${path}") path
154
+ else
155
+ let
156
+ paths = lib.splitString "/" path;
157
+ name = builtins.head paths;
158
+ input = inputs.${name} or (throw "Unknown input ${name}");
159
+ subpath = lib.concatStringsSep "/" (builtins.tail paths);
160
+ devenvpath = input + lib.optionalString (subpath != "") "/${subpath}";
161
+ in
162
+ tryImport devenvpath path;
163
+
164
+ # Common modules shared between main evaluation and cross-system evaluation
165
+ mkCommonModules =
166
+ evalPkgs:
167
+ [
168
+ (
169
+ { config, ... }:
170
+ {
171
+ _module.args.pkgs = evalPkgs.appendOverlays (config.overlays or [ ]);
172
+ _module.args.secretspec = secretspec;
173
+ _module.args.devenvPrimops = primops;
174
+ }
175
+ )
176
+ (inputs.devenv.modules + /top-level.nix)
177
+ (
178
+ { options, ... }:
179
+ {
180
+ config.devenv = lib.mkMerge [
181
+ {
182
+ root = devenv_root;
183
+ dotfile = devenv_dotfile;
184
+ }
185
+ (
186
+ if builtins.hasAttr "cli" options.devenv then
187
+ {
188
+ cli.version = version;
189
+ cli.isDevelopment = is_development_version;
190
+ }
191
+ else
192
+ {
193
+ cliVersion = version;
194
+ }
195
+ )
196
+ (lib.optionalAttrs
197
+ (builtins.hasAttr "cli" options.devenv && builtins.hasAttr "requireVersionMatch" options.devenv.cli)
198
+ {
199
+ cli.requireVersionMatch = require_version_match;
200
+ }
201
+ )
202
+ (lib.optionalAttrs (builtins.hasAttr "tmpdir" options.devenv) {
203
+ tmpdir = devenv_tmpdir;
204
+ })
205
+ (lib.optionalAttrs (builtins.hasAttr "isTesting" options.devenv) {
206
+ isTesting = devenv_istesting;
207
+ })
208
+ (lib.optionalAttrs (builtins.hasAttr "runtime" options.devenv) {
209
+ runtime = devenv_runtime;
210
+ })
211
+ (lib.optionalAttrs (builtins.hasAttr "state" options.devenv && devenv_state != null) {
212
+ state = lib.mkForce devenv_state;
213
+ })
214
+ (lib.optionalAttrs (builtins.hasAttr "direnvrcLatestVersion" options.devenv) {
215
+ direnvrcLatestVersion = devenv_direnvrc_latest_version;
216
+ })
217
+ ];
218
+ }
219
+ )
220
+ (
221
+ { options, ... }:
222
+ {
223
+ config = lib.mkMerge [
224
+ (lib.optionalAttrs (builtins.hasAttr "git" options) {
225
+ git.root = git_root;
226
+ })
227
+ ];
228
+ }
229
+ )
230
+ ]
231
+ ++ (lib.flatten (map importModule devenv_imports))
232
+ ++ (
233
+ if !skip_local_src then
234
+ (importModule (devenv_root + "/devenv.nix"))
235
+ ++ (
236
+ let
237
+ localPath = devenv_root + "/devenv.local.nix";
238
+ in
239
+ lib.optional (builtins.pathExists localPath) localPath
240
+ )
241
+ else
242
+ [ ]
243
+ )
244
+ ++ [
245
+ cli_options
246
+ ];
247
+
248
+ # Phase 1: Base evaluation to extract profile definitions
249
+ baseProject = lib.evalModules {
250
+ class = "devenv";
251
+ specialArgs = inputs // {
252
+ inherit inputs secretspec primops;
253
+ };
254
+ modules = mkCommonModules pkgsBootstrap;
255
+ };
256
+
257
+ # Phase 2: Extract and apply profiles using extendModules with priority overrides
258
+ project =
259
+ let
260
+ # Build ordered list of profile names: hostname -> user -> manual
261
+ manualProfiles = active_profiles;
262
+ currentHostname = hostname;
263
+ currentUsername = username;
264
+ hostnameProfiles = lib.optional (
265
+ currentHostname != null
266
+ && currentHostname != ""
267
+ && builtins.hasAttr currentHostname (baseProject.config.profiles.hostname or { })
268
+ ) "hostname.${currentHostname}";
269
+ userProfiles = lib.optional (
270
+ currentUsername != null
271
+ && currentUsername != ""
272
+ && builtins.hasAttr currentUsername (baseProject.config.profiles.user or { })
273
+ ) "user.${currentUsername}";
274
+
275
+ # Ordered list of profiles to activate
276
+ orderedProfiles = hostnameProfiles ++ userProfiles ++ manualProfiles;
277
+
278
+ # Resolve profile extends with cycle detection
279
+ resolveProfileExtends =
280
+ profileName: visited:
281
+ if builtins.elem profileName visited then
282
+ throw "Circular dependency detected in profile extends: ${lib.concatStringsSep " -> " visited} -> ${profileName}"
283
+ else
284
+ let
285
+ profile = getProfileConfig profileName;
286
+ extends = profile.extends or [ ];
287
+ newVisited = visited ++ [ profileName ];
288
+ extendedProfiles = lib.flatten (map (name: resolveProfileExtends name newVisited) extends);
289
+ in
290
+ extendedProfiles ++ [ profileName ];
291
+
292
+ # Get profile configuration by name from baseProject
293
+ getProfileConfig =
294
+ profileName:
295
+ if lib.hasPrefix "hostname." profileName then
296
+ let
297
+ name = lib.removePrefix "hostname." profileName;
298
+ in
299
+ baseProject.config.profiles.hostname.${name}
300
+ else if lib.hasPrefix "user." profileName then
301
+ let
302
+ name = lib.removePrefix "user." profileName;
303
+ in
304
+ baseProject.config.profiles.user.${name}
305
+ else
306
+ let
307
+ availableProfiles = builtins.attrNames (baseProject.config.profiles or { });
308
+ hostnameProfiles = map (n: "hostname.${n}") (
309
+ builtins.attrNames (baseProject.config.profiles.hostname or { })
310
+ );
311
+ userProfiles = map (n: "user.${n}") (builtins.attrNames (baseProject.config.profiles.user or { }));
312
+ allAvailableProfiles = availableProfiles ++ hostnameProfiles ++ userProfiles;
313
+ in
314
+ baseProject.config.profiles.${profileName}
315
+ or (throw "Profile '${profileName}' not found. Available profiles: ${lib.concatStringsSep ", " allAvailableProfiles}");
316
+
317
+ # Fold over ordered profiles to build final list with extends
318
+ expandedProfiles = lib.foldl' (
319
+ acc: profileName:
320
+ let
321
+ allProfileNames = resolveProfileExtends profileName [ ];
322
+ in
323
+ acc ++ allProfileNames
324
+ ) [ ] orderedProfiles;
325
+
326
+ # Map over expanded profiles and apply priorities
327
+ allPrioritizedModules = lib.imap0 (
328
+ index: profileName:
329
+ let
330
+ profilePriority = (lib.modules.defaultOverridePriority - 1) - index;
331
+ profileConfig = getProfileConfig profileName;
332
+
333
+ typeNeedsOverride =
334
+ type:
335
+ if type == null then
336
+ false
337
+ else
338
+ let
339
+ typeName = type.name or type._type or "";
340
+
341
+ isLeafType = builtins.elem typeName [
342
+ "str"
343
+ "int"
344
+ "bool"
345
+ "enum"
346
+ "path"
347
+ "package"
348
+ "float"
349
+ "anything"
350
+ ];
351
+ in
352
+ if isLeafType then
353
+ true
354
+ else if typeName == "nullOr" then
355
+ let
356
+ innerType =
357
+ type.elemType
358
+ or (if type ? nestedTypes && type.nestedTypes ? elemType then type.nestedTypes.elemType else null);
359
+ in
360
+ if innerType != null then typeNeedsOverride innerType else false
361
+ else
362
+ false;
363
+
364
+ pathNeedsOverride =
365
+ optionPath:
366
+ let
367
+ directOption = lib.attrByPath optionPath null baseProject.options;
368
+ in
369
+ if directOption != null && lib.isOption directOption then
370
+ typeNeedsOverride directOption.type
371
+ else if optionPath != [ ] then
372
+ let
373
+ parentPath = lib.init optionPath;
374
+ parentOption = lib.attrByPath parentPath null baseProject.options;
375
+ in
376
+ if parentOption != null && lib.isOption parentOption then
377
+ let
378
+ freeformType = parentOption.type.freeformType or parentOption.type.nestedTypes.freeformType or null;
379
+ elementType =
380
+ if freeformType ? elemType then
381
+ freeformType.elemType
382
+ else if freeformType ? nestedTypes && freeformType.nestedTypes ? elemType then
383
+ freeformType.nestedTypes.elemType
384
+ else
385
+ freeformType;
386
+ in
387
+ typeNeedsOverride elementType
388
+ else
389
+ false
390
+ else
391
+ false;
392
+
393
+ applyModuleOverride =
394
+ config:
395
+ if builtins.isFunction config then
396
+ let
397
+ wrapper = args: applyOverrideRecursive (config args) [ ];
398
+ in
399
+ lib.mirrorFunctionArgs config wrapper
400
+ else
401
+ applyOverrideRecursive config [ ];
402
+
403
+ applyOverrideRecursive =
404
+ config: optionPath:
405
+ if lib.isAttrs config && config ? _type then
406
+ config
407
+ else if pathNeedsOverride optionPath then
408
+ lib.mkOverride profilePriority config
409
+ else if lib.isAttrs config then
410
+ lib.mapAttrs (name: value: applyOverrideRecursive value (optionPath ++ [ name ])) config
411
+ else
412
+ config;
413
+
414
+ prioritizedConfig = (
415
+ profileConfig.module
416
+ // {
417
+ imports = lib.map (
418
+ importItem:
419
+ importItem
420
+ // {
421
+ imports = lib.map (nestedImport: applyModuleOverride nestedImport) (importItem.imports or [ ]);
422
+ }
423
+ ) (profileConfig.module.imports or [ ]);
424
+ }
425
+ );
426
+ in
427
+ prioritizedConfig
428
+ ) expandedProfiles;
429
+ in
430
+ if allPrioritizedModules == [ ] then
431
+ baseProject
432
+ else
433
+ baseProject.extendModules { modules = allPrioritizedModules; };
434
+
435
+ config = project.config;
436
+
437
+ # Per-container scoped re-evaluation that flips `isBuilding` for the
438
+ # container being built. Selecting one container cannot pollute the
439
+ # evaluation of any other operation, since each `containerBuilds.<name>`
440
+ # is its own `extendModules` scope.
441
+ mkContainerBuilds =
442
+ evalProject:
443
+ lib.genAttrs (lib.attrNames evalProject.config.containers) (
444
+ name:
445
+ let
446
+ scoped = evalProject.extendModules {
447
+ modules = [
448
+ {
449
+ container.isBuilding = lib.mkForce true;
450
+ containers.${name}.isBuilding = lib.mkForce true;
451
+ }
452
+ ];
453
+ };
454
+ in
455
+ scoped.config.containers.${name}
456
+ );
457
+
458
+ containerBuilds = mkContainerBuilds project;
459
+
460
+ # Apply config overlays to pkgs
461
+ pkgs = pkgsBootstrap.appendOverlays (config.overlays or [ ]);
462
+
463
+ options = pkgs.nixosOptionsDoc {
464
+ options = builtins.removeAttrs project.options [ "_module" ];
465
+ warningsAreErrors = false;
466
+ transformOptions =
467
+ let
468
+ isDocType =
469
+ v:
470
+ builtins.elem v [
471
+ "literalDocBook"
472
+ "literalExpression"
473
+ "literalMD"
474
+ "mdDoc"
475
+ ];
476
+ in
477
+ lib.attrsets.mapAttrs (
478
+ _: v:
479
+ if v ? _type && isDocType v._type then
480
+ v.text
481
+ else if v ? _type && v._type == "derivation" then
482
+ v.name
483
+ else
484
+ v
485
+ );
486
+ };
487
+
488
+ build =
489
+ options: config:
490
+ lib.concatMapAttrs (
491
+ name: option:
492
+ if lib.isOption option then
493
+ let
494
+ typeName = option.type.name or "";
495
+ in
496
+ if
497
+ builtins.elem typeName [
498
+ "output"
499
+ "outputOf"
500
+ ]
501
+ then
502
+ {
503
+ ${name} = config.${name};
504
+ }
505
+ else
506
+ { }
507
+ else if builtins.isAttrs option && !lib.isDerivation option then
508
+ let
509
+ v = build option config.${name};
510
+ in
511
+ if v != { } then { ${name} = v; } else { }
512
+ else
513
+ { }
514
+ ) options;
515
+
516
+ # Helper to evaluate devenv for a specific system (for cross-compilation, e.g. macOS building Linux containers)
517
+ evalForSystem =
518
+ evalSystem:
519
+ let
520
+ evalPkgs = mkPkgsForSystem evalSystem;
521
+ evalProject = lib.evalModules {
522
+ class = "devenv";
523
+ specialArgs = inputs // {
524
+ inherit inputs secretspec primops;
525
+ };
526
+ modules = mkCommonModules evalPkgs;
527
+ };
528
+ in
529
+ {
530
+ config = evalProject.config;
531
+ containerBuilds = mkContainerBuilds evalProject;
532
+ };
533
+
534
+ # All supported systems for cross-compilation (lazily evaluated)
535
+ allSystems = [
536
+ "x86_64-linux"
537
+ "aarch64-linux"
538
+ "x86_64-darwin"
539
+ "aarch64-darwin"
540
+ ];
541
+
542
+ # Generate perSystem entries for all systems (only evaluated when accessed)
543
+ perSystemConfigs = lib.genAttrs allSystems (
544
+ perSystem:
545
+ if perSystem == targetSystem then { inherit config containerBuilds; } else evalForSystem perSystem
546
+ );
547
+ in
548
+ {
549
+ inherit
550
+ pkgs
551
+ config
552
+ options
553
+ project
554
+ inputs
555
+ ;
556
+ bash = pkgs.bash;
557
+ shell = config.shell;
558
+ # Older pinned modules predate the optional localhost proxy.
559
+ processProxyEnabled = config.process.proxy.enable or false;
560
+ optionsJSON = options.optionsJSON;
561
+ info = config.info;
562
+ ci = config.ciDerivation;
563
+ build = build project.options config;
564
+ devenv = {
565
+ # Backwards compatibility: wrap config in devenv attribute for code expecting devenv.config.*
566
+ inherit config containerBuilds;
567
+ # perSystem structure for cross-compilation (e.g. macOS building Linux containers)
568
+ perSystem = perSystemConfigs;
569
+ };
570
+ };
571
+
572
+ # Simplified devenv evaluation for inputs
573
+ # This is a lightweight version suitable for evaluating an input's devenv.nix
574
+ mkDevenvForInput =
575
+ {
576
+ # The input to evaluate (must have outPath and sourceInfo)
577
+ input,
578
+ # All resolved inputs (for specialArgs)
579
+ allInputs,
580
+ # System to evaluate for
581
+ system ? builtins.currentSystem,
582
+ # Nixpkgs to use (defaults to allInputs.nixpkgs)
583
+ nixpkgs ? allInputs.nixpkgs or (throw "nixpkgs input required"),
584
+ # Devenv modules (defaults to allInputs.devenv)
585
+ devenv ? allInputs.devenv or (throw "devenv input required"),
586
+ }:
587
+ let
588
+ devenvPath = input.outPath + "/devenv.nix";
589
+ hasDevenv = builtins.pathExists devenvPath;
590
+ in
591
+ if !hasDevenv then
592
+ throw ''
593
+ Input does not have a devenv.nix file.
594
+ Expected file at: ${toString devenvPath}
595
+
596
+ To use this input's devenv configuration, the input must provide a devenv.nix file.
597
+ ''
598
+ else
599
+ let
600
+ pkgs = import nixpkgs {
601
+ inherit system;
602
+ config = { };
603
+ };
604
+ lib = pkgs.lib;
605
+
606
+ project = lib.evalModules {
607
+ class = "devenv";
608
+ specialArgs = allInputs // {
609
+ inputs = allInputs;
610
+ secretspec = null;
611
+ };
612
+ modules = [
613
+ (
614
+ { config, ... }:
615
+ {
616
+ _module.args.pkgs = pkgs.appendOverlays (config.overlays or [ ]);
617
+ }
618
+ )
619
+ (devenv.outPath + "/src/modules/top-level.nix")
620
+ devenvPath
621
+ ];
622
+ };
623
+ in
624
+ {
625
+ inherit pkgs;
626
+ config = project.config;
627
+ options = project.options;
628
+ inherit project;
629
+ };
630
+ }
@@ -0,0 +1,22 @@
1
+ args@{
2
+ system,
3
+ # The project root (location of devenv.nix)
4
+ devenv_root,
5
+ devenv_lock,
6
+ ...
7
+ }:
8
+
9
+ let
10
+ inherit
11
+ (import ./resolve-lock.nix {
12
+ src = devenv_root;
13
+ lockFilePath = devenv_lock;
14
+ inherit system;
15
+ })
16
+ inputs
17
+ ;
18
+
19
+ bootstrapLib = import ./bootstrapLib.nix { inherit inputs; };
20
+ in
21
+
22
+ bootstrapLib.mkDevenvForSystem args