@marcoappio/marco-config 4.0.23 → 4.0.24
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.
|
@@ -751,13 +751,13 @@ type AppwriteTableFields = AppwriteTableInput['fields'] & v.ObjectEntries;
|
|
|
751
751
|
type AppwriteObjectSchema<TFields extends AppwriteTableFields> = v.ObjectSchema<TFields, undefined>;
|
|
752
752
|
type AppwriteCheckedObjectSchema<TFields extends AppwriteTableFields> = v.SchemaWithPipe<readonly [AppwriteObjectSchema<TFields>, v.CheckAction<v.InferOutput<AppwriteObjectSchema<TFields>>, undefined>]>;
|
|
753
753
|
declare const wireMetadata: <const TTableId extends string, const TWirePermissions extends AppwriteTableInput['wirePermissions']>(tableId: TTableId, wirePermissions: TWirePermissions) => {
|
|
754
|
-
$createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
754
|
+
$createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TransformAction<string, string>, v.IsoTimestampAction<string, undefined>, v.CheckAction<string, undefined>]>;
|
|
755
755
|
$databaseId: v.LiteralSchema<"marco", undefined>;
|
|
756
756
|
$id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 36, undefined>, v.RegexAction<string, undefined>]>;
|
|
757
757
|
$permissions: v.ArraySchema<v.StringSchema<undefined>, undefined> | v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.LengthAction<string[], 0, undefined>]>;
|
|
758
758
|
$sequence: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
759
759
|
$tableId: v.LiteralSchema<TTableId, undefined>;
|
|
760
|
-
$updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
760
|
+
$updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TransformAction<string, string>, v.IsoTimestampAction<string, undefined>, v.CheckAction<string, undefined>]>;
|
|
761
761
|
};
|
|
762
762
|
type AppwriteDataSchemaFor<TTable extends AppwriteTableInput> = TTable extends {
|
|
763
763
|
readonly dataCheck: (input: unknown) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/appwrite/tableContract/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,6BAA6B,CAAA;AAK/C,OAAO,EACL,KAAK,wBAAwB,EAE7B,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/appwrite/tableContract/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { v } from '../../utils/valibot/index.js';
|
|
|
2
2
|
import { identityTableInputs } from './identity.js';
|
|
3
3
|
import { mailboxTableInputs } from './mailbox.js';
|
|
4
4
|
import { operationalTableInputs } from './operational.js';
|
|
5
|
-
import { appwriteIds, appwriteRowIdSchema, identifierSchema,
|
|
5
|
+
import { appwriteIds, appwriteRowIdSchema, identifierSchema, } from './shared.js';
|
|
6
6
|
export * from './shared.js';
|
|
7
7
|
const appwriteTableInputs = {
|
|
8
8
|
...identityTableInputs,
|
|
@@ -39,22 +39,32 @@ const materialiseTable = (key, id, table) => {
|
|
|
39
39
|
};
|
|
40
40
|
};
|
|
41
41
|
const wireMetadata = (tableId, wirePermissions) => ({
|
|
42
|
-
$createdAt:
|
|
42
|
+
$createdAt: appwriteRowTimestampSchema,
|
|
43
43
|
$databaseId: v.literal(appwriteIds.database),
|
|
44
44
|
$id: appwriteRowIdSchema,
|
|
45
45
|
$permissions: wirePermissions === 'empty' ? v.pipe(v.array(v.string()), v.length(0)) : v.array(v.string()),
|
|
46
46
|
$sequence: identifierSchema,
|
|
47
47
|
$tableId: v.literal(tableId),
|
|
48
|
-
$updatedAt:
|
|
48
|
+
$updatedAt: appwriteRowTimestampSchema,
|
|
49
49
|
});
|
|
50
|
-
|
|
50
|
+
const appwriteRowTimestampSchema = v.pipe(v.string(), v.transform(timestamp => (timestamp.endsWith('+00:00') ? `${timestamp.slice(0, -6)}Z` : timestamp)), v.isoTimestamp(), v.check(timestamp => {
|
|
51
|
+
const milliseconds = Date.parse(timestamp);
|
|
52
|
+
return Number.isFinite(milliseconds) && new Date(milliseconds).toISOString() === timestamp;
|
|
53
|
+
}));
|
|
54
|
+
const createDataSchema = (fields, dataCheck) => {
|
|
51
55
|
const schema = v.object(fields);
|
|
52
|
-
if (dataCheck) {
|
|
53
|
-
return
|
|
56
|
+
if (dataCheck === undefined) {
|
|
57
|
+
return schema;
|
|
54
58
|
}
|
|
55
|
-
return schema;
|
|
56
|
-
}
|
|
57
|
-
const createRowSchema = (fields, tableId, wirePermissions) =>
|
|
59
|
+
return v.pipe(schema, v.check(input => dataCheck(input)));
|
|
60
|
+
};
|
|
61
|
+
const createRowSchema = (fields, tableId, wirePermissions) => {
|
|
62
|
+
const rowFields = Object.fromEntries(Object.entries(fields).map(([key, field]) => {
|
|
63
|
+
const rowField = field.definition.type === 'datetime' ? (field.definition.required ? appwriteRowTimestampSchema : v.nullable(appwriteRowTimestampSchema)) : field;
|
|
64
|
+
return [key, rowField];
|
|
65
|
+
}));
|
|
66
|
+
return v.strictObject({ ...wireMetadata(tableId, wirePermissions), ...rowFields });
|
|
67
|
+
};
|
|
58
68
|
const isAppwriteTableKey = (tableKey) => Object.hasOwn(appwriteIds.tables, tableKey);
|
|
59
69
|
const appwriteTableIdentity = (tableKey) => {
|
|
60
70
|
if (isAppwriteTableKey(tableKey)) {
|
|
@@ -4,7 +4,7 @@ import { identityTableInputs } from './identity.js';
|
|
|
4
4
|
import { defineAppwriteTables } from './index.js';
|
|
5
5
|
import { mailboxTableInputs } from './mailbox.js';
|
|
6
6
|
import { operationalTableInputs } from './operational.js';
|
|
7
|
-
import { appwriteColumnDefinitions, appwriteIds, appwriteRelationship, appwriteRelationshipIdSchema, defineAppwriteTableGroup, identifierSchema } from './shared.js';
|
|
7
|
+
import { appwriteColumnDefinitions, appwriteIds, appwriteRelationship, appwriteRelationshipIdSchema, canonicalTimestampSchema, defineAppwriteTableGroup, identifierSchema, } from './shared.js';
|
|
8
8
|
const tableInputs = {
|
|
9
9
|
...identityTableInputs,
|
|
10
10
|
...mailboxTableInputs,
|
|
@@ -29,6 +29,28 @@ const validAccount = {
|
|
|
29
29
|
provider: 'GMAIL',
|
|
30
30
|
state: 'CONNECTED',
|
|
31
31
|
};
|
|
32
|
+
const validJob = {
|
|
33
|
+
$createdAt: '2026-08-04T22:20:58.706+00:00',
|
|
34
|
+
$databaseId: appwriteIds.database,
|
|
35
|
+
$id: 'test-job-id-1',
|
|
36
|
+
$permissions: [],
|
|
37
|
+
$sequence: '1',
|
|
38
|
+
$tableId: appwriteIds.tables.jobs,
|
|
39
|
+
$updatedAt: '2026-08-04T22:20:58.706+00:00',
|
|
40
|
+
accountId: null,
|
|
41
|
+
attempts: 0,
|
|
42
|
+
commandId: 'test-command-id-1',
|
|
43
|
+
dedupeKey: 'test-dedupe-key-1',
|
|
44
|
+
errorCode: null,
|
|
45
|
+
kind: 'mailbox.sync',
|
|
46
|
+
leaseExpiresAt: null,
|
|
47
|
+
leaseId: null,
|
|
48
|
+
maxAttempts: 3,
|
|
49
|
+
nextRunAt: '2026-08-04T22:20:58.706+00:00',
|
|
50
|
+
payload: '{}',
|
|
51
|
+
state: 'PENDING',
|
|
52
|
+
userId: 'test-user-id-1',
|
|
53
|
+
};
|
|
32
54
|
describe('defineAppwriteTables', () => {
|
|
33
55
|
it('constrains table group keys and index attributes at compile time', () => {
|
|
34
56
|
const fields = {
|
|
@@ -75,6 +97,29 @@ describe('defineAppwriteTables', () => {
|
|
|
75
97
|
expect(Object.fromEntries(Object.entries(contract.tables).map(([key, table]) => [key, table.id]))).toEqual(appwriteIds.tables);
|
|
76
98
|
expect(Object.entries(contract.tables).every(([key, table]) => table.key === key)).toBe(true);
|
|
77
99
|
});
|
|
100
|
+
it('normalises Appwrite datetime wire values in generated row schemas', () => {
|
|
101
|
+
const contract = defineAppwriteTables(tableInputs);
|
|
102
|
+
const parsed = v.safeParse(contract.rowSchemas.jobs, validJob);
|
|
103
|
+
expect(parsed.success).toBe(true);
|
|
104
|
+
if (parsed.success) {
|
|
105
|
+
expect(parsed.output.$createdAt).toBe('2026-08-04T22:20:58.706Z');
|
|
106
|
+
expect(parsed.output.nextRunAt).toBe('2026-08-04T22:20:58.706Z');
|
|
107
|
+
expect(parsed.output.leaseExpiresAt).toBeNull();
|
|
108
|
+
expect(parsed.output.$updatedAt).toBe('2026-08-04T22:20:58.706Z');
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
it('rejects invalid persisted timestamps while keeping canonical input strict', () => {
|
|
112
|
+
const contract = defineAppwriteTables(tableInputs);
|
|
113
|
+
const timestampSchema = contract.rowSchemas.jobs.entries.nextRunAt;
|
|
114
|
+
for (const [timestamp, expected] of [
|
|
115
|
+
['2026-08-05T00:20:58.706+02:00', false],
|
|
116
|
+
['2026-06-31T12:00:30.000Z', false],
|
|
117
|
+
['2026-08-04T22:20:58.706', false],
|
|
118
|
+
]) {
|
|
119
|
+
expect(v.safeParse(timestampSchema, timestamp).success).toBe(expected);
|
|
120
|
+
}
|
|
121
|
+
expect(v.safeParse(canonicalTimestampSchema, '2026-08-04T22:20:58.706+00:00').success).toBe(false);
|
|
122
|
+
});
|
|
78
123
|
it('rejects inherited object property names as table keys', () => {
|
|
79
124
|
expect(() => defineAppwriteTables({
|
|
80
125
|
...tableInputs,
|