includio-cms 0.36.6 → 0.36.8
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/API.md +8 -2
- package/CHANGELOG.md +30 -0
- package/DOCS.md +1 -1
- package/dist/admin/api/handler.js +2 -0
- package/dist/admin/api/media-jobs.d.ts +5 -0
- package/dist/admin/api/media-jobs.js +33 -0
- package/dist/admin/client/maintenance/maintenance-page.svelte +9 -0
- package/dist/admin/client/maintenance/media-jobs-panel.svelte +310 -0
- package/dist/admin/client/maintenance/media-jobs-panel.svelte.d.ts +3 -0
- package/dist/core/cms.js +7 -0
- package/dist/core/server/fields/utils/imageStyles.js +41 -4
- package/dist/core/server/index.d.ts +3 -0
- package/dist/core/server/index.js +3 -0
- package/dist/core/server/media/jobs/enqueue.d.ts +6 -0
- package/dist/core/server/media/jobs/enqueue.js +20 -0
- package/dist/core/server/media/jobs/processImageStyleJob.d.ts +19 -0
- package/dist/core/server/media/jobs/processImageStyleJob.js +23 -0
- package/dist/core/server/media/jobs/startWorker.d.ts +2 -0
- package/dist/core/server/media/jobs/startWorker.js +29 -0
- package/dist/core/server/media/jobs/worker.d.ts +29 -0
- package/dist/core/server/media/jobs/worker.js +54 -0
- package/dist/core/server/media/operations/replaceFile.js +2 -2
- package/dist/core/server/media/operations/uploadFile.js +10 -3
- package/dist/core/server/media/styles/buildStyleSpecs.d.ts +12 -0
- package/dist/core/server/media/styles/buildStyleSpecs.js +36 -0
- package/dist/core/server/media/styles/imagesConfig.d.ts +3 -0
- package/dist/core/server/media/styles/imagesConfig.js +16 -0
- package/dist/core/server/media/styles/operations/batchGenerateStyles.js +19 -41
- package/dist/core/server/media/styles/operations/generateFallbackVariant.d.ts +10 -0
- package/dist/core/server/media/styles/operations/generateFallbackVariant.js +21 -0
- package/dist/core/server/media/styles/operations/getImageStyle.js +12 -8
- package/dist/core/server/media/styles/sharp/sharpConfig.d.ts +7 -0
- package/dist/core/server/media/styles/sharp/sharpConfig.js +12 -0
- package/dist/db-postgres/index.js +113 -1
- package/dist/db-postgres/schema/imageStyle.js +1 -1
- package/dist/db-postgres/schema/index.d.ts +1 -0
- package/dist/db-postgres/schema/index.js +1 -0
- package/dist/db-postgres/schema/mediaFile.d.ts +17 -0
- package/dist/db-postgres/schema/mediaFile.js +1 -0
- package/dist/db-postgres/schema/mediaJob.d.ts +279 -0
- package/dist/db-postgres/schema/mediaJob.js +23 -0
- package/dist/paraglide/messages/_index.d.ts +36 -3
- package/dist/paraglide/messages/_index.js +71 -3
- package/dist/paraglide/messages/en.d.ts +5 -0
- package/dist/paraglide/messages/en.js +14 -0
- package/dist/paraglide/messages/pl.d.ts +5 -0
- package/dist/paraglide/messages/pl.js +14 -0
- package/dist/shop/adapters/fakturownia/payload.d.ts +2 -0
- package/dist/shop/adapters/fakturownia/payload.js +1 -0
- package/dist/shop/server/invoices.d.ts +16 -2
- package/dist/shop/server/invoices.js +86 -9
- package/dist/shop/types.d.ts +5 -0
- package/dist/sveltekit/components/image.svelte +1 -1
- package/dist/types/adapters/db.d.ts +51 -0
- package/dist/types/cms.d.ts +46 -0
- package/dist/types/media.d.ts +1 -0
- package/dist/updates/0.36.7/index.d.ts +2 -0
- package/dist/updates/0.36.7/index.js +13 -0
- package/dist/updates/0.36.8/index.d.ts +2 -0
- package/dist/updates/0.36.8/index.js +20 -0
- package/dist/updates/index.js +5 -1
- package/package.json +1 -1
- package/dist/paraglide/messages/hello_world.d.ts +0 -5
- package/dist/paraglide/messages/hello_world.js +0 -33
- package/dist/paraglide/messages/login_hello.d.ts +0 -16
- package/dist/paraglide/messages/login_hello.js +0 -34
- package/dist/paraglide/messages/login_please_login.d.ts +0 -16
- package/dist/paraglide/messages/login_please_login.js +0 -34
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
export declare const mediaJobTable: import("drizzle-orm/pg-core/table", { with: { "resolution-mode": "require" } }).PgTableWithColumns<{
|
|
2
|
+
name: "media_job";
|
|
3
|
+
schema: undefined;
|
|
4
|
+
columns: {
|
|
5
|
+
id: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
6
|
+
name: "id";
|
|
7
|
+
tableName: "media_job";
|
|
8
|
+
dataType: "string";
|
|
9
|
+
columnType: "PgUUID";
|
|
10
|
+
data: string;
|
|
11
|
+
driverParam: string;
|
|
12
|
+
notNull: true;
|
|
13
|
+
hasDefault: true;
|
|
14
|
+
isPrimaryKey: true;
|
|
15
|
+
isAutoincrement: false;
|
|
16
|
+
hasRuntimeDefault: false;
|
|
17
|
+
enumValues: undefined;
|
|
18
|
+
baseColumn: never;
|
|
19
|
+
identity: undefined;
|
|
20
|
+
generated: undefined;
|
|
21
|
+
}, {}, {}>;
|
|
22
|
+
type: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
23
|
+
name: "type";
|
|
24
|
+
tableName: "media_job";
|
|
25
|
+
dataType: "string";
|
|
26
|
+
columnType: "PgText";
|
|
27
|
+
data: string;
|
|
28
|
+
driverParam: string;
|
|
29
|
+
notNull: true;
|
|
30
|
+
hasDefault: false;
|
|
31
|
+
isPrimaryKey: false;
|
|
32
|
+
isAutoincrement: false;
|
|
33
|
+
hasRuntimeDefault: false;
|
|
34
|
+
enumValues: [string, ...string[]];
|
|
35
|
+
baseColumn: never;
|
|
36
|
+
identity: undefined;
|
|
37
|
+
generated: undefined;
|
|
38
|
+
}, {}, {}>;
|
|
39
|
+
mediaFileId: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
40
|
+
name: "media_file_id";
|
|
41
|
+
tableName: "media_job";
|
|
42
|
+
dataType: "string";
|
|
43
|
+
columnType: "PgUUID";
|
|
44
|
+
data: string;
|
|
45
|
+
driverParam: string;
|
|
46
|
+
notNull: true;
|
|
47
|
+
hasDefault: false;
|
|
48
|
+
isPrimaryKey: false;
|
|
49
|
+
isAutoincrement: false;
|
|
50
|
+
hasRuntimeDefault: false;
|
|
51
|
+
enumValues: undefined;
|
|
52
|
+
baseColumn: never;
|
|
53
|
+
identity: undefined;
|
|
54
|
+
generated: undefined;
|
|
55
|
+
}, {}, {}>;
|
|
56
|
+
payload: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
57
|
+
name: "payload";
|
|
58
|
+
tableName: "media_job";
|
|
59
|
+
dataType: "string";
|
|
60
|
+
columnType: "PgText";
|
|
61
|
+
data: string;
|
|
62
|
+
driverParam: string;
|
|
63
|
+
notNull: true;
|
|
64
|
+
hasDefault: false;
|
|
65
|
+
isPrimaryKey: false;
|
|
66
|
+
isAutoincrement: false;
|
|
67
|
+
hasRuntimeDefault: false;
|
|
68
|
+
enumValues: [string, ...string[]];
|
|
69
|
+
baseColumn: never;
|
|
70
|
+
identity: undefined;
|
|
71
|
+
generated: undefined;
|
|
72
|
+
}, {}, {}>;
|
|
73
|
+
dedupeKey: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
74
|
+
name: "dedupe_key";
|
|
75
|
+
tableName: "media_job";
|
|
76
|
+
dataType: "string";
|
|
77
|
+
columnType: "PgText";
|
|
78
|
+
data: string;
|
|
79
|
+
driverParam: string;
|
|
80
|
+
notNull: true;
|
|
81
|
+
hasDefault: false;
|
|
82
|
+
isPrimaryKey: false;
|
|
83
|
+
isAutoincrement: false;
|
|
84
|
+
hasRuntimeDefault: false;
|
|
85
|
+
enumValues: [string, ...string[]];
|
|
86
|
+
baseColumn: never;
|
|
87
|
+
identity: undefined;
|
|
88
|
+
generated: undefined;
|
|
89
|
+
}, {}, {}>;
|
|
90
|
+
status: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
91
|
+
name: "status";
|
|
92
|
+
tableName: "media_job";
|
|
93
|
+
dataType: "string";
|
|
94
|
+
columnType: "PgText";
|
|
95
|
+
data: string;
|
|
96
|
+
driverParam: string;
|
|
97
|
+
notNull: true;
|
|
98
|
+
hasDefault: true;
|
|
99
|
+
isPrimaryKey: false;
|
|
100
|
+
isAutoincrement: false;
|
|
101
|
+
hasRuntimeDefault: false;
|
|
102
|
+
enumValues: [string, ...string[]];
|
|
103
|
+
baseColumn: never;
|
|
104
|
+
identity: undefined;
|
|
105
|
+
generated: undefined;
|
|
106
|
+
}, {}, {}>;
|
|
107
|
+
priority: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
108
|
+
name: "priority";
|
|
109
|
+
tableName: "media_job";
|
|
110
|
+
dataType: "number";
|
|
111
|
+
columnType: "PgInteger";
|
|
112
|
+
data: number;
|
|
113
|
+
driverParam: string | number;
|
|
114
|
+
notNull: true;
|
|
115
|
+
hasDefault: true;
|
|
116
|
+
isPrimaryKey: false;
|
|
117
|
+
isAutoincrement: false;
|
|
118
|
+
hasRuntimeDefault: false;
|
|
119
|
+
enumValues: undefined;
|
|
120
|
+
baseColumn: never;
|
|
121
|
+
identity: undefined;
|
|
122
|
+
generated: undefined;
|
|
123
|
+
}, {}, {}>;
|
|
124
|
+
attempts: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
125
|
+
name: "attempts";
|
|
126
|
+
tableName: "media_job";
|
|
127
|
+
dataType: "number";
|
|
128
|
+
columnType: "PgInteger";
|
|
129
|
+
data: number;
|
|
130
|
+
driverParam: string | number;
|
|
131
|
+
notNull: true;
|
|
132
|
+
hasDefault: true;
|
|
133
|
+
isPrimaryKey: false;
|
|
134
|
+
isAutoincrement: false;
|
|
135
|
+
hasRuntimeDefault: false;
|
|
136
|
+
enumValues: undefined;
|
|
137
|
+
baseColumn: never;
|
|
138
|
+
identity: undefined;
|
|
139
|
+
generated: undefined;
|
|
140
|
+
}, {}, {}>;
|
|
141
|
+
maxAttempts: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
142
|
+
name: "max_attempts";
|
|
143
|
+
tableName: "media_job";
|
|
144
|
+
dataType: "number";
|
|
145
|
+
columnType: "PgInteger";
|
|
146
|
+
data: number;
|
|
147
|
+
driverParam: string | number;
|
|
148
|
+
notNull: true;
|
|
149
|
+
hasDefault: true;
|
|
150
|
+
isPrimaryKey: false;
|
|
151
|
+
isAutoincrement: false;
|
|
152
|
+
hasRuntimeDefault: false;
|
|
153
|
+
enumValues: undefined;
|
|
154
|
+
baseColumn: never;
|
|
155
|
+
identity: undefined;
|
|
156
|
+
generated: undefined;
|
|
157
|
+
}, {}, {}>;
|
|
158
|
+
lastError: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
159
|
+
name: "last_error";
|
|
160
|
+
tableName: "media_job";
|
|
161
|
+
dataType: "string";
|
|
162
|
+
columnType: "PgText";
|
|
163
|
+
data: string;
|
|
164
|
+
driverParam: string;
|
|
165
|
+
notNull: false;
|
|
166
|
+
hasDefault: false;
|
|
167
|
+
isPrimaryKey: false;
|
|
168
|
+
isAutoincrement: false;
|
|
169
|
+
hasRuntimeDefault: false;
|
|
170
|
+
enumValues: [string, ...string[]];
|
|
171
|
+
baseColumn: never;
|
|
172
|
+
identity: undefined;
|
|
173
|
+
generated: undefined;
|
|
174
|
+
}, {}, {}>;
|
|
175
|
+
runAfter: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
176
|
+
name: "run_after";
|
|
177
|
+
tableName: "media_job";
|
|
178
|
+
dataType: "date";
|
|
179
|
+
columnType: "PgTimestamp";
|
|
180
|
+
data: Date;
|
|
181
|
+
driverParam: string;
|
|
182
|
+
notNull: true;
|
|
183
|
+
hasDefault: true;
|
|
184
|
+
isPrimaryKey: false;
|
|
185
|
+
isAutoincrement: false;
|
|
186
|
+
hasRuntimeDefault: false;
|
|
187
|
+
enumValues: undefined;
|
|
188
|
+
baseColumn: never;
|
|
189
|
+
identity: undefined;
|
|
190
|
+
generated: undefined;
|
|
191
|
+
}, {}, {}>;
|
|
192
|
+
lockedAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
193
|
+
name: "locked_at";
|
|
194
|
+
tableName: "media_job";
|
|
195
|
+
dataType: "date";
|
|
196
|
+
columnType: "PgTimestamp";
|
|
197
|
+
data: Date;
|
|
198
|
+
driverParam: string;
|
|
199
|
+
notNull: false;
|
|
200
|
+
hasDefault: false;
|
|
201
|
+
isPrimaryKey: false;
|
|
202
|
+
isAutoincrement: false;
|
|
203
|
+
hasRuntimeDefault: false;
|
|
204
|
+
enumValues: undefined;
|
|
205
|
+
baseColumn: never;
|
|
206
|
+
identity: undefined;
|
|
207
|
+
generated: undefined;
|
|
208
|
+
}, {}, {}>;
|
|
209
|
+
lockedBy: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
210
|
+
name: "locked_by";
|
|
211
|
+
tableName: "media_job";
|
|
212
|
+
dataType: "string";
|
|
213
|
+
columnType: "PgText";
|
|
214
|
+
data: string;
|
|
215
|
+
driverParam: string;
|
|
216
|
+
notNull: false;
|
|
217
|
+
hasDefault: false;
|
|
218
|
+
isPrimaryKey: false;
|
|
219
|
+
isAutoincrement: false;
|
|
220
|
+
hasRuntimeDefault: false;
|
|
221
|
+
enumValues: [string, ...string[]];
|
|
222
|
+
baseColumn: never;
|
|
223
|
+
identity: undefined;
|
|
224
|
+
generated: undefined;
|
|
225
|
+
}, {}, {}>;
|
|
226
|
+
createdAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
227
|
+
name: "created_at";
|
|
228
|
+
tableName: "media_job";
|
|
229
|
+
dataType: "date";
|
|
230
|
+
columnType: "PgTimestamp";
|
|
231
|
+
data: Date;
|
|
232
|
+
driverParam: string;
|
|
233
|
+
notNull: true;
|
|
234
|
+
hasDefault: true;
|
|
235
|
+
isPrimaryKey: false;
|
|
236
|
+
isAutoincrement: false;
|
|
237
|
+
hasRuntimeDefault: false;
|
|
238
|
+
enumValues: undefined;
|
|
239
|
+
baseColumn: never;
|
|
240
|
+
identity: undefined;
|
|
241
|
+
generated: undefined;
|
|
242
|
+
}, {}, {}>;
|
|
243
|
+
updatedAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
244
|
+
name: "updated_at";
|
|
245
|
+
tableName: "media_job";
|
|
246
|
+
dataType: "date";
|
|
247
|
+
columnType: "PgTimestamp";
|
|
248
|
+
data: Date;
|
|
249
|
+
driverParam: string;
|
|
250
|
+
notNull: true;
|
|
251
|
+
hasDefault: true;
|
|
252
|
+
isPrimaryKey: false;
|
|
253
|
+
isAutoincrement: false;
|
|
254
|
+
hasRuntimeDefault: false;
|
|
255
|
+
enumValues: undefined;
|
|
256
|
+
baseColumn: never;
|
|
257
|
+
identity: undefined;
|
|
258
|
+
generated: undefined;
|
|
259
|
+
}, {}, {}>;
|
|
260
|
+
completedAt: import("drizzle-orm/pg-core", { with: { "resolution-mode": "require" } }).PgColumn<{
|
|
261
|
+
name: "completed_at";
|
|
262
|
+
tableName: "media_job";
|
|
263
|
+
dataType: "date";
|
|
264
|
+
columnType: "PgTimestamp";
|
|
265
|
+
data: Date;
|
|
266
|
+
driverParam: string;
|
|
267
|
+
notNull: false;
|
|
268
|
+
hasDefault: false;
|
|
269
|
+
isPrimaryKey: false;
|
|
270
|
+
isAutoincrement: false;
|
|
271
|
+
hasRuntimeDefault: false;
|
|
272
|
+
enumValues: undefined;
|
|
273
|
+
baseColumn: never;
|
|
274
|
+
identity: undefined;
|
|
275
|
+
generated: undefined;
|
|
276
|
+
}, {}, {}>;
|
|
277
|
+
};
|
|
278
|
+
dialect: "pg";
|
|
279
|
+
}>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { integer, pgTable, text, timestamp, uniqueIndex, index, uuid } from 'drizzle-orm/pg-core';
|
|
2
|
+
export const mediaJobTable = pgTable('media_job', {
|
|
3
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
4
|
+
type: text('type').notNull(), // 'image_style' (na start; rozszerzalne: video_poster, video_transcode)
|
|
5
|
+
mediaFileId: uuid('media_file_id').notNull(),
|
|
6
|
+
payload: text('payload').notNull(), // JSON.stringify(ImageFieldStyle)
|
|
7
|
+
dedupeKey: text('dedupe_key').notNull(),
|
|
8
|
+
status: text('status').notNull().default('pending'), // pending|processing|done|failed|skipped
|
|
9
|
+
priority: integer('priority').notNull().default(0), // wyżej = pilniejsze
|
|
10
|
+
attempts: integer('attempts').notNull().default(0),
|
|
11
|
+
maxAttempts: integer('max_attempts').notNull().default(3),
|
|
12
|
+
lastError: text('last_error'),
|
|
13
|
+
runAfter: timestamp('run_after').notNull().defaultNow(),
|
|
14
|
+
lockedAt: timestamp('locked_at'),
|
|
15
|
+
lockedBy: text('locked_by'),
|
|
16
|
+
createdAt: timestamp('created_at').notNull().defaultNow(),
|
|
17
|
+
updatedAt: timestamp('updated_at').notNull().defaultNow(),
|
|
18
|
+
completedAt: timestamp('completed_at')
|
|
19
|
+
}, (t) => [
|
|
20
|
+
uniqueIndex('media_job_dedupe_key').on(t.dedupeKey),
|
|
21
|
+
index('media_job_claim_idx').on(t.status, t.runAfter, t.priority),
|
|
22
|
+
index('media_job_media_idx').on(t.mediaFileId)
|
|
23
|
+
]);
|
|
@@ -1,3 +1,36 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export function hello_world(inputs: {
|
|
2
|
+
name: NonNullable<unknown>;
|
|
3
|
+
}, options?: {
|
|
4
|
+
locale?: "en" | "pl";
|
|
5
|
+
}): string;
|
|
6
|
+
/**
|
|
7
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
8
|
+
*
|
|
9
|
+
* - Changing this function will be over-written by the next build.
|
|
10
|
+
*
|
|
11
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
12
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
13
|
+
*
|
|
14
|
+
* @param {{}} inputs
|
|
15
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
declare function login_hello(inputs?: {}, options?: {
|
|
19
|
+
locale?: "en" | "pl";
|
|
20
|
+
}): string;
|
|
21
|
+
/**
|
|
22
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
23
|
+
*
|
|
24
|
+
* - Changing this function will be over-written by the next build.
|
|
25
|
+
*
|
|
26
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
27
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
28
|
+
*
|
|
29
|
+
* @param {{}} inputs
|
|
30
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
declare function login_please_login(inputs?: {}, options?: {
|
|
34
|
+
locale?: "en" | "pl";
|
|
35
|
+
}): string;
|
|
36
|
+
export { login_hello as login.hello, login_please_login as login.please_login };
|
|
@@ -1,4 +1,72 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { getLocale, trackMessageCall, experimentalMiddlewareLocaleSplitting, isServer } from "../runtime.js"
|
|
3
|
+
import * as en from "./en.js"
|
|
4
|
+
import * as pl from "./pl.js"
|
|
5
|
+
/**
|
|
6
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
7
|
+
*
|
|
8
|
+
* - Changing this function will be over-written by the next build.
|
|
9
|
+
*
|
|
10
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
11
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
12
|
+
*
|
|
13
|
+
* @param {{ name: NonNullable<unknown> }} inputs
|
|
14
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
18
|
+
export const hello_world = (inputs, options = {}) => {
|
|
19
|
+
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
20
|
+
return /** @type {any} */ (globalThis).__paraglide_ssr.hello_world(inputs)
|
|
21
|
+
}
|
|
22
|
+
const locale = options.locale ?? getLocale()
|
|
23
|
+
trackMessageCall("hello_world", locale)
|
|
24
|
+
if (locale === "en") return en.hello_world(inputs)
|
|
25
|
+
return pl.hello_world(inputs)
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
29
|
+
*
|
|
30
|
+
* - Changing this function will be over-written by the next build.
|
|
31
|
+
*
|
|
32
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
33
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
34
|
+
*
|
|
35
|
+
* @param {{}} inputs
|
|
36
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
40
|
+
const login_hello = (inputs = {}, options = {}) => {
|
|
41
|
+
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
42
|
+
return /** @type {any} */ (globalThis).__paraglide_ssr.login_hello(inputs)
|
|
43
|
+
}
|
|
44
|
+
const locale = options.locale ?? getLocale()
|
|
45
|
+
trackMessageCall("login_hello", locale)
|
|
46
|
+
if (locale === "en") return en.login_hello(inputs)
|
|
47
|
+
return pl.login_hello(inputs)
|
|
48
|
+
};
|
|
49
|
+
export { login_hello as "login.hello" }
|
|
50
|
+
/**
|
|
51
|
+
* This function has been compiled by [Paraglide JS](https://inlang.com/m/gerre34r).
|
|
52
|
+
*
|
|
53
|
+
* - Changing this function will be over-written by the next build.
|
|
54
|
+
*
|
|
55
|
+
* - If you want to change the translations, you can either edit the source files e.g. `en.json`, or
|
|
56
|
+
* use another inlang app like [Fink](https://inlang.com/m/tdozzpar) or the [VSCode extension Sherlock](https://inlang.com/m/r7kp499g).
|
|
57
|
+
*
|
|
58
|
+
* @param {{}} inputs
|
|
59
|
+
* @param {{ locale?: "en" | "pl" }} options
|
|
60
|
+
* @returns {string}
|
|
61
|
+
*/
|
|
62
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
63
|
+
const login_please_login = (inputs = {}, options = {}) => {
|
|
64
|
+
if (experimentalMiddlewareLocaleSplitting && isServer === false) {
|
|
65
|
+
return /** @type {any} */ (globalThis).__paraglide_ssr.login_please_login(inputs)
|
|
66
|
+
}
|
|
67
|
+
const locale = options.locale ?? getLocale()
|
|
68
|
+
trackMessageCall("login_please_login", locale)
|
|
69
|
+
if (locale === "en") return en.login_please_login(inputs)
|
|
70
|
+
return pl.login_please_login(inputs)
|
|
71
|
+
};
|
|
72
|
+
export { login_please_login as "login.please_login" }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const hello_world = /** @type {(inputs: { name: NonNullable<unknown> }) => string} */ (i) => {
|
|
5
|
+
return `Hello, ${i.name} from en!`
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const login_hello = /** @type {(inputs: {}) => string} */ () => {
|
|
9
|
+
return `Welcome back`
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const login_please_login = /** @type {(inputs: {}) => string} */ () => {
|
|
13
|
+
return `Login to your account`
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const hello_world = /** @type {(inputs: { name: NonNullable<unknown> }) => string} */ (i) => {
|
|
5
|
+
return `Hello, ${i.name} from pl!`
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const login_hello = /** @type {(inputs: {}) => string} */ () => {
|
|
9
|
+
return `Witaj ponownie`
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const login_please_login = /** @type {(inputs: {}) => string} */ () => {
|
|
13
|
+
return `Zaloguj się na swoje konto`
|
|
14
|
+
};
|
|
@@ -25,6 +25,8 @@ export interface FakturowniaInvoiceBody {
|
|
|
25
25
|
buyer_city?: string;
|
|
26
26
|
buyer_post_code?: string;
|
|
27
27
|
buyer_country?: string;
|
|
28
|
+
/** Printed remarks ("Uwagi") — e.g. the applied coupon code. */
|
|
29
|
+
description?: string;
|
|
28
30
|
positions: FakturowniaPosition[];
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
@@ -39,6 +39,7 @@ export function buildFakturowniaInvoice(payload, opts = {}) {
|
|
|
39
39
|
? { buyer_post_code: pick(buyer.address, 'postCode', 'zip', 'postalCode') }
|
|
40
40
|
: {}),
|
|
41
41
|
...(pick(buyer.address, 'country') ? { buyer_country: pick(buyer.address, 'country') } : {}),
|
|
42
|
+
...(payload.note ? { description: payload.note } : {}),
|
|
42
43
|
positions: payload.items.map((item) => ({
|
|
43
44
|
name: item.name,
|
|
44
45
|
quantity: item.quantity,
|
|
@@ -44,8 +44,22 @@ export declare function decideInvoiceAction(order: InvoiceOrderState, existing:
|
|
|
44
44
|
} | null, policy: InvoiceIssuePolicy, opts?: {
|
|
45
45
|
force?: boolean;
|
|
46
46
|
}): InvoiceAction;
|
|
47
|
-
/**
|
|
48
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Map order + items onto the provider-agnostic {@link InvoicePayload}. Pure.
|
|
49
|
+
* `opts.discount` lowers the item prices to the post-discount amounts and adds a
|
|
50
|
+
* remark (`note`) with the coupon code; `opts.shipping` appends a "Wysyłka" line
|
|
51
|
+
* when charged (>0). Together the line totals equal `order.totalGross`.
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildInvoicePayload(order: InvoiceOrderData, items: InvoiceItemData[], paidAt: string, opts?: {
|
|
54
|
+
discount?: {
|
|
55
|
+
code: string;
|
|
56
|
+
amount: number;
|
|
57
|
+
};
|
|
58
|
+
shipping?: {
|
|
59
|
+
net: number;
|
|
60
|
+
gross: number;
|
|
61
|
+
};
|
|
62
|
+
}): InvoicePayload;
|
|
49
63
|
export declare function getInvoiceByOrderId(orderId: string): Promise<InvoiceRow | null>;
|
|
50
64
|
/**
|
|
51
65
|
* Issue an invoice for an order if it qualifies. Fire-and-forget, fail-open —
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { eq } from 'drizzle-orm';
|
|
2
2
|
import { shopInvoicesTable, shopOrderItemsTable, shopOrdersTable } from '../../db-postgres/schema/shop/index.js';
|
|
3
3
|
import { getShopDb, requireShopConfig } from './db.js';
|
|
4
|
+
import { getOrderCoupon } from './coupons.js';
|
|
4
5
|
const FULLY_PAID_STATES = new Set(['paid', 'preparing', 'sent', 'done']);
|
|
5
6
|
export class InvoiceError extends Error {
|
|
6
7
|
code;
|
|
@@ -59,8 +60,82 @@ function lineName(name) {
|
|
|
59
60
|
return `${product} — ${variant}`;
|
|
60
61
|
return product || variant || Object.values(name)[0] || '';
|
|
61
62
|
}
|
|
62
|
-
/**
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Build the shipping invoice line, or `null` when shipping is free. VAT is
|
|
65
|
+
* reconstructed from the actually-charged net/gross (falls back to 23% when the
|
|
66
|
+
* net is zero but a gross was charged). Pure.
|
|
67
|
+
*/
|
|
68
|
+
function buildShippingLine(shipping) {
|
|
69
|
+
if (shipping.gross <= 0)
|
|
70
|
+
return null;
|
|
71
|
+
const vatRate = shipping.net > 0 ? Math.round(((shipping.gross - shipping.net) / shipping.net) * 100) : 23;
|
|
72
|
+
return { name: 'Wysyłka', quantity: 1, unitPriceGross: shipping.gross, vatRate };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reduce item line prices by a gross coupon discount, so the invoice shows the
|
|
76
|
+
* actually-charged (post-discount) prices — the final total equals the amount
|
|
77
|
+
* paid (`order.totalGross`). The gross discount is distributed across lines
|
|
78
|
+
* proportionally to each line's gross share; the last line absorbs the rounding
|
|
79
|
+
* remainder so the reduced line totals sum to `subtotal − discountAmount`
|
|
80
|
+
* exactly. The per-unit price may carry fractional grosze; the provider
|
|
81
|
+
* recomputes it from the line total (Fakturownia: `total_price_gross ÷ quantity`).
|
|
82
|
+
* Pure.
|
|
83
|
+
*/
|
|
84
|
+
function applyDiscountToLines(lines, discountAmount) {
|
|
85
|
+
if (discountAmount <= 0 || lines.length === 0)
|
|
86
|
+
return lines;
|
|
87
|
+
const lineGross = (l) => l.unitPriceGross * l.quantity;
|
|
88
|
+
const subtotal = lines.reduce((s, l) => s + lineGross(l), 0);
|
|
89
|
+
if (subtotal <= 0)
|
|
90
|
+
return lines;
|
|
91
|
+
let allocated = 0;
|
|
92
|
+
return lines.map((line, idx) => {
|
|
93
|
+
const gross = lineGross(line);
|
|
94
|
+
const isLast = idx === lines.length - 1;
|
|
95
|
+
const lineDiscount = isLast
|
|
96
|
+
? discountAmount - allocated
|
|
97
|
+
: Math.round((discountAmount * gross) / subtotal);
|
|
98
|
+
allocated += lineDiscount;
|
|
99
|
+
return { ...line, unitPriceGross: (gross - lineDiscount) / line.quantity };
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/** Format minor units (grosze) as a localized currency string. Pure. */
|
|
103
|
+
function formatMoney(grosze, currency, language) {
|
|
104
|
+
return new Intl.NumberFormat(language === 'en' ? 'en-GB' : 'pl-PL', {
|
|
105
|
+
style: 'currency',
|
|
106
|
+
currency,
|
|
107
|
+
minimumFractionDigits: 2
|
|
108
|
+
}).format(grosze / 100);
|
|
109
|
+
}
|
|
110
|
+
/** Build the printed invoice remark describing the applied coupon. Pure. */
|
|
111
|
+
function discountNote(discount, currency, language) {
|
|
112
|
+
const amount = formatMoney(discount.amount, currency, language);
|
|
113
|
+
return language === 'en'
|
|
114
|
+
? `Discount code ${discount.code} applied (-${amount}).`
|
|
115
|
+
: `Zastosowano kod rabatowy ${discount.code} (rabat -${amount}).`;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Map order + items onto the provider-agnostic {@link InvoicePayload}. Pure.
|
|
119
|
+
* `opts.discount` lowers the item prices to the post-discount amounts and adds a
|
|
120
|
+
* remark (`note`) with the coupon code; `opts.shipping` appends a "Wysyłka" line
|
|
121
|
+
* when charged (>0). Together the line totals equal `order.totalGross`.
|
|
122
|
+
*/
|
|
123
|
+
export function buildInvoicePayload(order, items, paidAt, opts = {}) {
|
|
124
|
+
let lines = items.map((item) => ({
|
|
125
|
+
name: lineName(item.nameSnapshot),
|
|
126
|
+
quantity: item.qty,
|
|
127
|
+
unitPriceGross: item.priceGrossSnapshot,
|
|
128
|
+
vatRate: item.vatRate
|
|
129
|
+
}));
|
|
130
|
+
const hasDiscount = Boolean(opts.discount && opts.discount.amount > 0);
|
|
131
|
+
if (opts.discount && hasDiscount) {
|
|
132
|
+
lines = applyDiscountToLines(lines, opts.discount.amount);
|
|
133
|
+
}
|
|
134
|
+
if (opts.shipping) {
|
|
135
|
+
const shippingLine = buildShippingLine(opts.shipping);
|
|
136
|
+
if (shippingLine)
|
|
137
|
+
lines.push(shippingLine);
|
|
138
|
+
}
|
|
64
139
|
return {
|
|
65
140
|
orderNumber: order.number,
|
|
66
141
|
currency: order.currency,
|
|
@@ -72,12 +147,10 @@ export function buildInvoicePayload(order, items, paidAt) {
|
|
|
72
147
|
companyName: order.customerCompanyName,
|
|
73
148
|
address: order.billingAddress ?? order.shippingAddress ?? null
|
|
74
149
|
},
|
|
75
|
-
items:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
vatRate: item.vatRate
|
|
80
|
-
}))
|
|
150
|
+
items: lines,
|
|
151
|
+
...(opts.discount && hasDiscount
|
|
152
|
+
? { note: discountNote(opts.discount, order.currency, order.language) }
|
|
153
|
+
: {})
|
|
81
154
|
};
|
|
82
155
|
}
|
|
83
156
|
export async function getInvoiceByOrderId(orderId) {
|
|
@@ -144,7 +217,11 @@ async function runCreate(order, existing, adapter) {
|
|
|
144
217
|
.from(shopOrderItemsTable)
|
|
145
218
|
.where(eq(shopOrderItemsTable.orderId, order.id));
|
|
146
219
|
const paidAt = order.partialPayment?.paidAt ?? now.toISOString();
|
|
147
|
-
const
|
|
220
|
+
const coupon = await getOrderCoupon(order.id);
|
|
221
|
+
const payload = buildInvoicePayload(toOrderData(order), toItemData(items), paidAt, {
|
|
222
|
+
discount: coupon ? { code: coupon.code, amount: coupon.discountAmount } : undefined,
|
|
223
|
+
shipping: { net: order.shippingNet, gross: order.shippingGross }
|
|
224
|
+
});
|
|
148
225
|
try {
|
|
149
226
|
const result = await adapter.createInvoice(payload, { language: order.language });
|
|
150
227
|
let status = 'issued';
|
package/dist/shop/types.d.ts
CHANGED
|
@@ -359,6 +359,11 @@ export interface InvoicePayload {
|
|
|
359
359
|
items: InvoiceLineItem[];
|
|
360
360
|
/** ISO timestamp the payment was confirmed — used as issue / paid date. */
|
|
361
361
|
paidAt: string;
|
|
362
|
+
/**
|
|
363
|
+
* Free-text remark printed on the invoice (e.g. the applied coupon code).
|
|
364
|
+
* Adapters map it onto their notes field (Fakturownia: `description`).
|
|
365
|
+
*/
|
|
366
|
+
note?: string;
|
|
362
367
|
}
|
|
363
368
|
/** @public */
|
|
364
369
|
export interface InvoiceCreateResult {
|